σμ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 3 · Wahrscheinlichkeit & Monte-Carlo-Simulation›Thema 3.8·~40 Min.Mittelstufe

Drawdowns

Position in der SkillModul 3 von 11 · Thema 8 von 12
3.8 Drawdowns
—Lab-Punkte— / 100XP gesamt—Serie—

Der Verlust, den man wirklich spürt

Volatilität behandelt Auf und Ab gleich, doch ein Anleger lebt mit einer anderen Zahl: wie weit das Depot unter dem besten Wert liegt, den es je hatte. Das ist der Drawdown. Stieg ein Portfolio auf 110 und steht jetzt bei 98, liegt es 10,9 % unter seinem Höchststand, was auch die Tagesvolatilität sagt. Der maximale Drawdown ist das tiefste solche Loch der Historie, die Zeit unter Wasser die Dauer, bis man wieder heraus war. Kunden steigen bei Drawdowns aus und Risikomanager kürzen Limits bei Drawdowns, nicht bei Standardabweichungen.

import pandas as pd

prices = pd.Series(
    [100, 105, 103, 98, 104, 110, 108, 107, 111, 95], dtype=float,
    index=pd.bdate_range("2026-03-02", periods=10),
)

peak = prices.cummax()                 # the highest price so far, day by day
drawdown = prices / peak - 1           # 0 on a new high, negative below it

print(peak.tolist())                   # [100.0, 105.0, 105.0, 105.0, 105.0, 110.0, 110.0, 110.0, 111.0, 111.0]
print(drawdown.round(4).tolist())      # [0.0, 0.0, -0.019, -0.0667, -0.0095, 0.0, -0.0182, -0.0273, 0.0, -0.1441]

Das tiefste Loch

cummax() liefert den laufenden Höchststand in einem Aufruf. Den Preis dadurch zu teilen und 1 abzuziehen ergibt an jedem Tag den Drawdown, stets null oder negativ. Der maximale Drawdown ist einfach das Minimum dieser Reihe, und idxmin() sagt, wann er auftrat. Drawdowns sind auf wichtige Weise asymmetrisch: Ein Verlust von 20 % braucht 25 % Gewinn, um zurückzukommen, 1 / (1 - 0,20) - 1, einer von 50 % braucht 100 %. Deshalb kämpfen Risikomanager für flache Drawdowns.

print(round(drawdown.min(), 4), drawdown.idxmin().date())   # -0.1441 2026-03-13   111 down to 95

# The climb back is steeper than the fall
for loss in (0.10, 0.20, 0.50):
    print(loss, round(1 / (1 - loss) - 1, 3))
# 0.1 0.111
# 0.2 0.25
# 0.5 1.0

Die Zeit unter Wasser

Die Tiefe ist nur die halbe Geschichte, die Dauer die andere Hälfte. Eine Strategie kann nur 8 % verlieren und trotzdem drei Jahre unter ihrem alten Hoch verbringen, was die Geduld jedes Anlegers prüft. Ein Tag ist unter Wasser, solange sein Drawdown negativ ist, und ein neues Hoch beendet die Phase. Um mit pandas die längste Phase zu finden, markieren Sie die Tage unter Wasser durch einen Vergleich, nummerieren jede Folge gleicher Werte mit (flag != flag.shift()).cumsum() und zählen innerhalb jeder Folge. Eine einfache Schleife, die zählt und zurücksetzt, geht genauso gut und liest sich leicht.

underwater = drawdown < 0                                     # True while below the running peak
run_id = (underwater != underwater.shift()).cumsum()           # a new id each time the flag changes
streak = underwater.astype(int).groupby(run_id).cumsum()       # 1, 2, 3, ... inside each underwater run

print(streak.tolist())                    # [0, 0, 1, 2, 3, 0, 1, 2, 0, 1]
print(int(streak.max()))                  # 3   the longest wait for a new high, in days
# Return divided by the depth of the worst hole: the Calmar ratio
annual_return = 0.12
print(round(annual_return / abs(drawdown.min()), 2))     # 0.83
Ein vergangener Drawdown ist nicht der schlimmsteDer maximale Drawdown eines Backtests ist der schlimmste in dieser Stichprobe, nicht der schlimmste mögliche: Eine längere Historie enthält fast immer ein tieferes Loch. Betrachten Sie ihn als Untergrenze, vergleichen Sie ihn mit dem größten Drawdown des Marktes im selben Zeitraum und lassen Sie bei den Positionsgrößen einen Puffer.
  • peak = prices.cummax() und drawdown = prices / peak - 1: null bei neuem Hoch, darunter negativ.
  • Der maximale Drawdown ist drawdown.min(); ein Verlust von x braucht einen Gewinn von 1 / (1 - x) - 1 zur Erholung.
  • Die Zeit unter Wasser ist die längste Folge von Tagen mit negativem Drawdown; der schlimmste Drawdown eines Backtests ist eine Untergrenze, keine Garantie.

Als Nächstes: Zufallszahlengeneratoren und Seeds, die Grundlage jeder Simulation.

Lab: Was bewertet wird

  • Mit running_peak den bisherigen Höchststand verfolgen25 Pkt.
  • Mit drawdown_series den Abstand zum Höchststand messen25 Pkt.
  • Mit max_drawdown den schlimmsten Einbruch finden25 Pkt.
  • Mit longest_underwater das längste Warten auf ein neues Hoch zählen25 Pkt.
Explorer · lab-61-1
▾ lab-61-1
…
bash · im Browser
learner@quantcraft:~/lab-61-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

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