σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademySkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
Skills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python-Skill›Modul 1 · Python-Grundlagen für Quants›Thema 1.28·~35 Min.Einsteiger

Dataclasses

Position in der SkillModul 1 von 11 · Thema 28 von 33
1.28 Dataclasses
—Lab-Punkte— / 100XP gesamt—Serie—

Weniger Boilerplate für Klassen, die Daten halten

Viele Klassen existieren vor allem, um ein paar Felder zu halten: einen Trade, einen Kurs, eine Konfiguration. __init__, __repr__ und __eq__ für jede zu schreiben ist repetitiv. Der Decorator @dataclass aus dem Modul dataclasses schreibt sie aus einer Liste annotierter Felder für Sie. Sie deklarieren symbol: str, price: float, quantity: int einmal und erhalten einen Konstruktor Trade("AAPL", 184.25, 200), ein lesbares repr wie Trade(symbol='AAPL', price=184.25, quantity=200) und feldweise Gleichheit. Die Annotationen dokumentieren die Absicht; Python erzwingt sie nicht.

from dataclasses import dataclass

@dataclass
class Trade:
    symbol: str
    price: float
    quantity: int

a = Trade("AAPL", 184.25, 200)
b = Trade("AAPL", 184.25, 200)

print(a)                       # Trade(symbol='AAPL', price=184.25, quantity=200)
print(a == b)                  # True: compared field by field
print(a.price * a.quantity)    # 36850.0

Standardwerte, field() und veränderliche Werte

Ein Feld kann einen Standardwert haben (currency: str = "USD"), und Felder mit Standardwert müssen nach denen ohne stehen. Bei einem veränderlichen Standardwert wie einer Liste würde ein einfaches = [] von allen Objekten geteilt (und Python lehnt es ab); schreiben Sie trades: list = field(default_factory=list), damit jedes Objekt eine eigene neue Liste bekommt. Mit field(...) lässt sich ein Feld auch aus dem repr (repr=False) oder aus Vergleichen (compare=False) ausnehmen.

from dataclasses import dataclass, field

@dataclass
class Book:
    name: str
    currency: str = "USD"                       # a default
    trades: list = field(default_factory=list)  # a fresh list per object

one = Book("desk-a")
two = Book("desk-b")
one.trades.append(("AAPL", 100))

print(one)                  # Book(name='desk-a', currency='USD', trades=[('AAPL', 100)])
print(two.trades)           # []   (not shared)
print(Book("x", "EUR"))     # Book(name='x', currency='EUR', trades=[])

Eigene Methoden, __post_init__ und alternative Konstruktoren

Eine Dataclass bleibt eine normale Klasse, Sie können also Methoden hinzufügen. __post_init__(self) läuft direkt nach dem generierten __init__, der richtige Ort, um Werte zu prüfen oder zu bereinigen (self.symbol = self.symbol.upper(), raise ValueError(...) bei schlechtem Preis). Eine @classmethod erhält die Klasse als cls und ist der übliche Weg, ein Objekt aus einer anderen Form zu bauen, etwa aus Text: Trade.from_line("AAPL,184.25,200") liefert cls(symbol, float(price), int(quantity)), sodass die Prüfung weiterläuft und auch Unterklassen funktionieren.

from dataclasses import dataclass

@dataclass
class Trade:
    symbol: str
    price: float
    quantity: int

    def __post_init__(self):
        self.symbol = self.symbol.strip().upper()
        if self.price <= 0:
            raise ValueError("price must be positive")

    def notional(self):
        return self.price * abs(self.quantity)

    @classmethod
    def from_line(cls, line):
        symbol, price, quantity = line.split(",")
        return cls(symbol, float(price), int(quantity))

t = Trade.from_line(" aapl,184.25,-200")
print(t)              # Trade(symbol='AAPL', price=184.25, quantity=-200)
print(t.notional())   # 36850.0

Eingefroren, geordnet und wann normale Klassen gewinnen

@dataclass(frozen=True) macht Instanzen schreibgeschützt (Zuweisung an ein Feld löst FrozenInstanceError aus) und gibt ihnen einen Hash, sodass sie Dictionary-Schlüssel oder Mengenmitglieder sein können: ideal für Werte, die sich nicht ändern dürfen, etwa eine Kontraktspezifikation. @dataclass(order=True) fügt <, <=, >, >= hinzu, die die Felder der Reihe nach vergleichen. Nutzen Sie eine Dataclass für Datensätze; für Objekte mit viel Verhalten und verstecktem Zustand ist eine von Hand geschriebene Klasse mit sorgfältigen Methoden klarer.

from dataclasses import dataclass

@dataclass(frozen=True, order=True)
class Contract:
    symbol: str
    expiry: str          # ISO dates sort correctly as text

a = Contract("ESZ5", "2025-12-19")
b = Contract("ESZ5", "2026-03-20")
print(a < b)                          # True
print({a: "front", b: "next"}[a])     # front  (frozen => hashable)

try:
    a.symbol = "NQZ5"
except Exception as error:
    print(type(error).__name__)       # FrozenInstanceError
Prüfen Sie dort, wo die Daten hereinkommenAnnotationen wie price: float verhindern nicht, dass Trade("AAPL", "abc", 1) erzeugt wird. Würden schlechte Werte spätere Berechnungen stillschweigend verfälschen, prüfen Sie sie in __post_init__ und lösen ValueError aus, damit ein kaputter Datensatz gar nicht existieren kann. Erzeugen Sie Objekte stets über den normalen Konstruktor, auch aus from_line, damit die Prüfung nicht umgangen werden kann.
  • @dataclass macht aus annotierten Feldern __init__, __repr__ und __eq__.
  • Standardwerte stehen zuletzt; nutzen Sie field(default_factory=list) für Listen und Dictionaries.
  • __post_init__ prüft; @classmethod baut aus anderen Formen; frozen=True macht Werte schreibgeschützt.

Als Nächstes: Ableitungen im Code, die Änderungsrate einer Größe schätzen, die Idee hinter Options-Sensitivitäten wie Delta und Gamma.

Lab: Was bewertet wird

  • Mit __post_init__ einen Trade bereinigen und prüfen25 Pkt.
  • Mit notional den gehandelten Wert berechnen25 Pkt.
  • Mit from_line einen Trade aus Text bauen25 Pkt.
  • Mit net_quantity die Trades eines Symbols saldieren25 Pkt.
Explorer · lab-28-1
▾ lab-28-1
…
bash · im Browser
learner@quantcraft:~/lab-28-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-28-1 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen

Melde dich an, um deinen Code auszuführen.

Alle Lektionen kannst du kostenlos lesen. Erstelle ein Konto oder melde dich an, um Code auszuführen, Tests zu starten und dieses Lab abzugeben.

  • IDE im Browser mit Bash-Terminal — nichts zu installieren
  • Sofortige Bewertung, XP und dein Platz auf der Skill
Konto erstellenAnmelden
ODER
Weiter mit GitHub