σμ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 10 · Hochleistungs-Python-Entwicklung›Thema 10.1·~45 Min.Fortgeschritten

Sauberer Code

Position in der SkillModul 10 von 11 · Thema 1 von 13
10.1 Sauberer Code
—Lab-Punkte— / 100XP gesamt—Serie—

Code wird viel öfter gelesen als geschrieben

Eine Trading-Codebasis lebt Jahre und wird von Leuten geändert, die sie nicht geschrieben haben, oft unter Druck und oft von Ihnen selbst, sechs Monate später. Sauberer Code lässt sich schnell verstehen und sicher ändern. Es geht nicht um Stilregeln, sondern darum, eine falsche Änderung sichtbar zu machen. Eine schlecht benannte Funktion, die drei Dinge tut und ein Limit in einer Formel versteckt, ist der Ort der teuren Bugs, etwa ein Risikolimit, von dem niemand wusste, dass es fest einprogrammiert war.

# The same calculation, written two ways
def f(d, e, m, w):
    r = []
    if sum([abs(x) for x in d.values()]) / e > m:
        r.append("LEVERAGE")
    for k in sorted(d):
        if abs(d[k]) / sum([abs(x) for x in d.values()]) > w:
            r.append("CONCENTRATION:" + k)
    return r

book = {"AAPL": 80_000.0, "MSFT": -10_000.0, "NVDA": 10_000.0}
print(f(book, 50_000.0, 1.5, 0.5))                  # works, but what is d? e? m? w?

Namen, kleine Funktionen, keine versteckten Zahlen

Drei Gewohnheiten leisten das Meiste. Benennen Sie Dinge nach dem, was sie sind: gross_exposure statt f, max_leverage statt m. Halten Sie Funktionen klein und einzweckig: Jede erledigt eine Aufgabe, die sich in wenigen Worten benennen lässt, ist so einzeln testbar und wiederverwendbar, und eine größere Funktion entsteht durch ihren Aufruf. Vergraben Sie keine Zahlen: Ein Limit wie 1.5 mitten in einer Formel ist eine magische Zahl, die niemand sicher finden oder ändern kann; übergeben Sie es als Argument (oder benennen Sie es als Konstante). Die Brutto-Exposure einmal in einer eigenen Funktion zu berechnen, beseitigt zudem den wiederholten Ausdruck.

# Small functions with names that say what they return; the limits come in as arguments
def gross_exposure(positions):
    return sum(abs(value) for value in positions.values())

def leverage(positions, equity):
    return gross_exposure(positions) / equity

def risk_flags(positions, equity, max_leverage, max_weight):
    flags = []
    if leverage(positions, equity) > max_leverage:
        flags.append("LEVERAGE")
    gross = gross_exposure(positions)
    for symbol in sorted(positions):
        if abs(positions[symbol]) / gross > max_weight:
            flags.append(f"CONCENTRATION:{symbol}")
    return flags

book = {"AAPL": 80_000.0, "MSFT": -10_000.0, "NVDA": 10_000.0}
print(risk_flags(book, 50_000.0, 1.5, 0.5))         # ['LEVERAGE', 'CONCENTRATION:AAPL']
print(risk_flags(book, 50_000.0, 3.0, 0.9))         # []  the same code, looser limits

Ränder absichern und das Warum sagen

Behandeln Sie die schlechte Eingabe zuerst und geben Sie sofort zurück oder lösen Sie aus (eine Guard Clause), damit sich der Hauptpfad ohne Verschachtelung geradeaus liest. Ein Hebel gross / equity bei Eigenkapital null sollte ein klarer ValueError sein, kein ZeroDivisionError aus der Tiefe, und ein leeres Buch sollte 0.0 ergeben statt abzustürzen. Kommentare sollten das Warum erklären, das der Code nicht sagen kann (# die Börse rundet auf den Cent), nicht das Was wiederholen, das der Code schon zeigt. Docstrings sagen, was eine Funktion nimmt und liefert. Bevorzugen Sie schließlich reine Funktionen, die nur von ihren Argumenten abhängen und keine Nebenwirkungen haben: Sie lassen sich mit wenigen Eingaben testen.

# A guard clause stops bad input at the door and says exactly what is wrong
def leverage(positions, equity):
    if equity <= 0:
        raise ValueError("equity must be positive")
    return sum(abs(value) for value in positions.values()) / equity

print(leverage({"AAPL": 60_000.0, "MSFT": -30_000.0}, 45_000.0))     # 2.0
print(leverage({}, 45_000.0))                                         # 0.0  an empty book is fine

try:
    leverage({"AAPL": 60_000.0}, 0.0)
except ValueError as error:
    print("rejected:", error)                                         # rejected: equity must be positive
# A pure function answers the same way every time; hidden state does not
history = []

def running_notional(price, quantity):          # remembers earlier calls: the answer depends on the past
    history.append(price * quantity)
    return sum(history)

def notional(price, quantity):                  # depends only on its arguments
    return price * quantity

print(running_notional(10.0, 5), running_notional(10.0, 5))     # 50.0 100.0  same call, different answers
print(notional(10.0, 5), notional(10.0, 5))                     # 50.0 50.0   always the same
Sauber heißt nicht cleverKomprimieren Sie Code nicht, um klug zu wirken: Eine dreizeilige Schleife, die alle verstehen, schlägt einen einzeiligen Trick, der einen Kommentar braucht. Zerlegen Sie ihn aber auch nicht in Dutzende winziger Funktionen; hören Sie auf, wenn eine Funktion wie ein klarer Schritt liest. Und Aufräumen ist eine andere Änderung als eine Verhaltensänderung: Refaktorieren Sie mit bestehenden Tests davor und danach, damit jeder Unterschied von der neuen Logik und nicht vom Aufräumen kommt.
  • Benennen Sie Dinge nach dem, was sie sind, halten Sie Funktionen klein und einzweckig und bauen Sie größere durch deren Aufruf.
  • Keine magischen Zahlen: Limits kommen als Argumente oder benannte Konstanten; berechnen Sie einen wiederholten Wert nur einmal.
  • Sichern Sie schlechte Eingaben zuerst mit einem klaren Fehler ab, kommentieren Sie das Warum statt des Was und bevorzugen Sie testbare reine Funktionen.

Als Nächstes: Typannotationen und statische Prüfung, Werkzeuge Fehler finden lassen, bevor der Code läuft.

Lab: Was bewertet wird

  • Mit net_exposure das Buch saldieren25 Pkt.
  • Mit gross_exposure jede Position addieren25 Pkt.
  • Den Nenner in leverage absichern25 Pkt.
  • Die Prüfungen in risk_flags zusammensetzen25 Pkt.
Explorer · lab-117-1
▾ lab-117-1
…
bash · im Browser
learner@quantcraft:~/lab-117-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-117-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