Backtesting mit Python: Frameworks und eigene Lösungen.
Es gibt drei Wege, in Python Backtests zu bauen: fertige Frameworks, vektorisiertes Pandas, oder Event-Driven-Simulation. Jeder hat einen Sweet-Spot. Wer alle drei kennt, wählt für jedes Projekt das passende Werkzeug.
Die drei Ebenen.
Ebene 1: Vektorisiertes Backtesting (Pandas/NumPy)
Schnellste Methode, ideal für Strategie-Discovery und Parameter-Sweeps. Alle Signale werden auf einem DataFrame berechnet, Positionen mit Shift gegen Look-Ahead-Bias.
import pandas as pd
def simple_ma_backtest(prices, fast=20, slow=50):
df = prices.to_frame('close')
df['fast_ma'] = df['close'].rolling(fast).mean()
df['slow_ma'] = df['close'].rolling(slow).mean()
# Signal: 1 wenn fast > slow, sonst 0
df['signal'] = (df['fast_ma'] > df['slow_ma']).astype(int)
# SHIFT 1: Signal von gestern bestimmt heutige Position
df['position'] = df['signal'].shift(1).fillna(0)
df['return'] = df['close'].pct_change()
df['strat_return'] = df['return'] * df['position']
df['equity'] = (1 + df['strat_return']).cumprod()
return df
Vorteile: ultra-schnell (1 Mio. Bars in unter einer Sekunde), klar
zu debuggen, niedrige Komplexität.
Nachteile: schwierig für realistische Order-Logik (Limit-Orders,
partielle Fills), schwierig für Multi-Asset-Portfolio mit Constraints, kein
realistisches Position-Sizing.
Wann nutzen: erste Discovery-Phase, Parameter-Sweep, Long-Only-
Strategien auf einem Asset.
Ebene 2: Fertige Frameworks (vectorbt, backtrader)
Wenn die Strategie komplexer wird, lohnen Frameworks. Die zwei Hauptkandidaten:
- vectorbt: hochperformant, vektorisiert. Sweet-Spot für Strategien mit klaren Entry/Exit-Signalen. Multi-Asset out-of-the-box.
- backtrader: event-driven, fühlt sich wie ein „echter Markt" an. Langsamer, aber realistischer für komplexe Orders und Position-Sizing.
vectorbt für Strategy-Discovery, backtrader für Final-Validation und Übergang zur Live-Strategie. Beide haben Lernkurven — eine Woche Doku lesen, bevor man produktiv wird.
Ebene 3: Eigene Event-Driven-Backtester
Wenn die Strategie wirklich komplex wird (Order-Book-basiert, Multi-Currency mit Konvertierung, Hedging-Logik), schreibt man irgendwann einen eigenen Backtester. Das ist nicht trivial — aber für institutionelle Setups oft unvermeidlich.
Mindest-Komponenten:
- Data-Handler: lädt historische Bars/Ticks und liefert sie zeitlich geordnet.
- Strategy-Logic: bekommt jeden Datenpunkt, generiert Signale.
- Portfolio: hält aktuelle Positionen, P&L, verfügbares Kapital.
- Execution-Simulator: bekommt Orders, simuliert realistische Fills mit Slippage und Kosten.
- Performance-Analyzer: berechnet Sharpe, Sortino, Drawdowns, Trade-Statistiken.
Realistische Kosten-Modellierung.
Egal welche Ebene: Kosten sind das, woran 90 % der naiven Backtests scheitern. Mindest-Modell:
def trade_cost(order_size, price, bid_ask_spread, slippage_factor=0.5):
"""Gibt Kosten in Basis-Points zurück."""
notional = order_size * price
# Halber Spread als Mindestkosten
spread_cost = order_size * bid_ask_spread / 2
# Slippage skaliert mit Order-Größe relativ zum durchschnittlichen Volumen
slippage = slippage_factor * bid_ask_spread * order_size
# Kommission (Beispiel IBKR Aktien)
commission = max(1.0, 0.005 * order_size)
return spread_cost + slippage + commission
Performance-Metriken, die wirklich zählen.
- CAGR: annualisierte Rendite. Marketing-Metrik.
- Sharpe-Ratio: Rendite pro Einheit Risiko. Wichtig — aber verzerrt bei nicht-normalen Renditen.
- Sortino-Ratio: wie Sharpe, aber nur Downside-Vola im Nenner. Besser für asymmetrische Strategien.
- Max. Drawdown: größter Peak-to-Trough-Verlust. Psychologisch entscheidend.
- Calmar-Ratio: CAGR / Max. DD. Für Tail-Risiko relevant.
- Profit-Factor: Gewinne / Verluste. > 1,5 ist gut.
- Win-Rate: % gewinnender Trades. Allein nichts wert — muss im Kontext mit Avg-Win/Avg-Loss gelesen werden.
Die fünf häufigsten Backtest-Fallen.
(Siehe auch separater Artikel zu Backtest-Fallen.)
- Look-Ahead-Bias: Signal-Berechnung nutzt Daten von „heute" für Trade-Entscheidung „heute". Fix:
.shift(1)auf Signal. - Survivorship-Bias: Test nur auf heute existierenden Aktien. Fix: historische Index-Mitgliedschaft pflegen.
- Optimierung gegen Backtest: 1000 Parameter-Kombinationen testen, beste nehmen. Fix: Walk-Forward-Analyse.
- Unrealistische Order-Fills: angenommen, Sie kaufen jede Limit-Order zum Limit-Preis. In Realität: 60–80 % werden gefüllt, Rest verfällt. Fix: probabilistisches Fill-Modell.
- Daten-Snooping über Strategie-Varianten: 50 Strategien gebaut, 3 sehen gut aus, eine wird live geschickt. Fix: Out-of-Sample-Period komplett bis zum Ende beiseitelegen.
Mein Empfehlungs-Stack.
Für ein typisches Setup, das Sie selbst aufbauen wollen:
- Discovery: Pandas + NumPy. Iteration in Minuten.
- Validierung: vectorbt für Multi-Asset-Tests, Sensitivity-Analysen.
- Walk-Forward: eigener Loop mit dem oben genannten Walk-Forward-Code.
- Realistische Simulation: backtrader oder eigener Event-Driven-Simulator.
- Live-Transition: gleiche Strategie-Klasse von Backtester zu Live-Engine portieren — minimaler Code-Diff zwischen Backtest und Live ist Gold wert.
Was wir konkret nutzen.
Bei uns sind 80 % der ersten Strategie-Tests reine Pandas-Backtests in einem Jupyter-Notebook. 20 % laufen in einem eigenen Event-Driven-Framework, das wir über Jahre aufgebaut haben — speziell mit realistischer Order-Simulation für Optionen- und Multi-Asset-Strategien.
Es gibt kein „bestes" Framework. Es gibt nur das Framework, das zu Ihrer Strategie und Ihrem Reifegrad passt. Wer bei jedem neuen Projekt vom dritten Tag an einen Event-Driven-Backtester schreibt, kommt nie zu echten Strategien. Wer mit vectorbt eine Optionsstrategie testen will, bekommt unrealistische Ergebnisse. Das richtige Werkzeug für den richtigen Job.
Sie wollen Ihren Backtest-Stack aufbauen oder ein bestehendes Setup überprüfen? Erstgespräch buchen — wir setzen das Framework auf, das zu Ihren Strategien passt.