⚠ Trading ist mit einem erheblichen Verlustrisiko verbunden. Alle Inhalte dieser Website dienen ausschließlich der Bildung und stellen keine Finanzberatung dar.
Lektion 13 von 13 · Kostenlos

Ein vollständiges Research-Notebook-Projekt von den Daten bis zum Bericht, mit einer Code-Review-Checkliste gegen Look-Ahead-Bias und Überanpassung

Organisieren Sie eine vollständige Strategiestudie als reproduzierbares Projekt, führen Sie sie von den Rohdaten bis zu einem schriftlichen Ergebnis durch und prüfen Sie den Code mit einer Checkliste, die die Fehler aufdeckt, die Backtests schönfärben.

Autor: Moustafa HijaziInhalt geprüft: 2026-10-306 Min. LesezeitSelbstlernkurs

Was Sie lernen werden

  • Eine Ordner- und Notebook-Struktur, die eine Studie in sechs Monaten für Sie selbst oder für jeden anderen reproduzierbar macht.
  • Die Reihenfolge der Arbeit: Daten, Bereinigung, Features, Signale, Backtest, Kennzahlen, Out-of-Sample-Prüfung, Bericht.
  • Eine zeilenweise Code-Review-Checkliste für Look-Ahead-Bias, Survivorship-Bias und Überanpassung.
  • Wie Sie ein Ergebnis ehrlich aufschreiben, einschließlich dessen, was ausprobiert wurde und nicht funktioniert hat.

Erklärung

Out-of-Sample-Tests, Parameterplateaus und die Kosten vieler Versuche wurden in „Systematisches Trading“ (Lektionen 6 und 7) behandelt. In dieser Lektion geht es um das Engineering, das diese Ideen tragfähig macht: eine Projektstruktur, einen festen Arbeitsablauf und ein Review, das eine andere Person wiederholen könnte.

Projektstruktur

  • project/
  • data/raw/ # Downloads, nie von Hand bearbeitet
  • data/clean/ # Parquet-Dateien, erzeugt von 01_data.ipynb
  • notebooks/ # 01_data, 02_features, 03_backtest, 04_report
  • src/ # indicators.py, engine.py, metrics.py (Lektionen 6, 8, 9)
  • tests/ # test_metrics.py, test_engine.py
  • config.yaml # Ticker, Datumsangaben, Parameter, Kostenannahmen
  • requirements.txt # festgeschriebene Versionen: pandas==2.x, numpy==…

Wiederverwendeter Code liegt in src/; Notebooks rufen nur Funktionen auf und zeigen Ergebnisse. Schreiben Sie die Paketversionen fest, denn ein pandas-Update kann eine Standardeinstellung ändern (Frequenz-Strings, Resampling-Beschriftungen) und Ihre Zahlen verschieben. Setzen Sie für jede Zufallskomponente einen Seed und halten Sie das Download-Datum der Daten im Bericht fest.

Der Arbeitsablauf in der richtigen Reihenfolge

  1. Zuerst die Hypothese. Ein Satz ökonomischer Begründung und die exakten Regeln, bevor Sie Daten anfassen („Systematisches Trading“, Lektion 2). Legen Sie die Aufteilung in In-Sample und Out-of-Sample jetzt fest und öffnen Sie die Out-of-Sample-Datei erst in Schritt 7.
  2. Daten. Herunterladen, roh speichern, Quelle und Adjustierungsmethode dokumentieren (Lektion 4). Eine Liste der „heutigen Indexmitglieder“, die zehn Jahre zurück getestet wird, ist Survivorship-Bias.
  3. Bereinigen und validieren. Lücken, Duplikate, Nullkurse, Zeitzonen; in data/clean/ speichern.
  4. Features und Signale mit den getesteten Funktionen aus src/; jedes Feature auf Balken t nutzt nur Daten bis t.
  5. Backtest mit der Engine aus Lektion 8, einschließlich des Kostenmodells („Systematisches Trading“, Lektion 8).
  6. Kennzahlen und Charts (Lektionen 9 und 10) auf dem In-Sample-Zeitraum, mit einem kleinen Parameterraster, nicht mit einer Suche nach der besten Zelle.
  7. Out-of-Sample einmal ausführen, mit eingefrorenen Parametern. Halten Sie das Ergebnis fest, wie auch immer es ausfällt.
  8. Bericht: Hypothese, Daten, Regeln, Kosten, beide Ergebnistabellen, Charts, Anzahl der getesteten Varianten, Entscheidung.

Code-Review-Checkliste

Prüfen Sie Ihr Notebook so, als wäre es das eines anderen; jede Zeile ist eine Ja-oder-Nein-Frage.

Bereich Prüfung Typische Korrektur
Timing Wird jedes Signal um einen Balken verschoben, bevor es eine Position festlegt? pos = signal.shift(1)
Timing Verwenden rollierende Fenster center=False (die Standardeinstellung) und kein bfill()? Zentrierung und Rückwärtsauffüllung entfernen
Timing Werden Normalisierungen (Z-Scores, Ränge, Scaler) nur auf vergangenen Daten angepasst? Expandierende oder rollierende Anpassung
Daten Ist das Anlageuniversum so definiert, wie es zum jeweiligen Datum bekannt war? Zeitpunktgenaue Listen der Indexbestandteile oder ein ehrlicher Vorbehalt
Daten Werden adjustierte Kurse für Renditen und, wo relevant, unadjustierte für Stop-Abstände verwendet? Beide Spalten behalten
Ausführungen Werden Kurslücken zur Eröffnung ausgeführt, nicht zum Stop- oder Signalkurs? min(open, stop)
Kosten Werden Provisionen, Spread und Slippage pro Trade und pro Seite angesetzt? Kostenmodell in der Konfiguration
Überanpassung Wie viele Parametersätze, Regeln und Universen wurden ausprobiert? Steht die Anzahl im Bericht? Jeden Lauf protokollieren
Überanpassung Liefern benachbarte Parameter ähnliche Ergebnisse (ein Plateau)? Heatmap des Rasters
Überanpassung Wurden Out-of-Sample-Daten mehr als einmal angefasst? Falls ja, sind sie jetzt In-Sample; neue Daten suchen
Reproduzierbarkeit Reproduziert „Restart kernel and run all“ die Zahlen im Bericht? Versteckten Zustand und Zellreihenfolge korrigieren

Faustregel für die Signifikanz: Die t-Statistik einer annualisierten Sharpe Ratio beträgt ungefähr Sharpe × √Jahre. Eine Sharpe von 0.8 über vier Jahre ergibt 1.6, unter der üblichen Schwelle von etwa 2, und das noch bevor die Zahl der getesteten Varianten berücksichtigt wird; unter zwanzig Versuchen ist zu erwarten, dass der beste rein zufällig gut aussieht.

Durchgerechnetes Beispiel

Hypothetisches Beispiel, alle Zahlen erfunden. Ein Trader testet „Kauf bei einem 100-Tage-Ausbruch, Ausstieg über einen Trailing-Stop von 3 × ATR“ auf 30 Large-Cap-Aktien, 2014–2025, mit 0.1 % Kosten pro Seite.

  1. Aufteilung. In-Sample 2014–2021 (8 Jahre), Out-of-Sample 2022–2025 (4 Jahre), festgelegt vor dem ersten Lauf.
  2. Raster. Ausbruchslängen 50, 100, 150 × ATR-Multiplikatoren 2, 3, 4 = 9 Varianten, protokolliert. Die In-Sample-Sharpe reicht von 0.6 bis 1.1, die beste Zelle liegt bei (100, 3) = 1.1; ihre Nachbarn liegen bei 0.9 und 1.0, ein Plateau, also wird die Wahl beibehalten.
  3. Review. Die Checkliste deckt auf, dass die ATR-Spalte rolling(14).mean() auf der True Range von heute für den heutigen Stop verwendet hat. Die Engine wird so geändert, dass sie die ATR des vorherigen Balkens nutzt (Lektion 8). Die In-Sample-Sharpe fällt von 1.1 auf 1.0; der maximale Drawdown bleibt unverändert bei −22 %.
  4. Out-of-Sample. Einmal ausgeführt: Sharpe 0.6, CAGR 7.2 %, maximaler Drawdown −19 %, 118 Trades. Signifikanz: 0.6 × √4 = 1.2; der In-Sample-Wert ergab 1.0 × √8 = 2.8. Das Out-of-Sample-Ergebnis ist positiv, für sich genommen aber statistisch schwach.
  5. Entscheidung im Bericht. „Die Regel hat Out-of-Sample etwa 60 % ihrer In-Sample-Sharpe behalten (0.6 / 1.0), auf einem Plateau, 9 Varianten getestet, ein Look-Ahead-Fehler behoben. Die Evidenz ist bescheiden; der nächste Schritt sind sechs Monate Paper-Trading mit dem Skript aus Lektion 12, kein echtes Kapital.“ Gebühren modelliert; Steuern und Finanzierung nicht berücksichtigt.

Häufiger Fehler

„Nur zur Kontrolle“ einen Blick auf den Out-of-Sample-Zeitraum werfenJeder Blick auf die zurückgehaltenen Daten und jede danach vorgenommene Anpassung macht sie zu In-Sample-Daten. Haben Sie den ATR-Multiplikator geändert, nachdem Sie 2022–2025 gesehen haben, bleiben als ehrliche Optionen nur, zu berichten, dass der Test nicht mehr Out-of-Sample ist, oder neue Daten zu suchen, zum Beispiel andere Märkte oder die seither vergangenen Monate. Schreiben Sie das Datum der Aufteilung und das Datum, an dem der Out-of-Sample-Lauf ausgeführt wurde, in den Bericht.

Übungsaufgabe

Auf Papier: Prüfen Sie dieses Notebook-Fragment und das darauf folgende Ergebnis.

  • df['z'] = (df.close - df.close.mean()) / df.close.std()
  • df['signal'] = df.z < -1.5
  • df['pos'] = df.signal.astype(int)
  • df['ret'] = df.close.pct_change() * df.pos

In-Sample-Sharpe 2.4 über 6 Jahre; Out-of-Sample-Sharpe −0.3 über 2 Jahre. (a) Benennen Sie zwei Look-Ahead-Probleme im Code. (b) Berechnen Sie die ungefähren t-Statistiken für die In-Sample- und die Out-of-Sample-Sharpe. (c) Schreiben Sie die vier Zeilen so um, dass sie frei von Look-Ahead sind (oder beschreiben Sie die Änderungen in Worten, wenn Ihnen das lieber ist).

Lösung anzeigen

(a) Erstens verwenden df.close.mean() und df.close.std() die gesamte Stichprobe einschließlich zukünftiger Kurse, sodass der Z-Score an jedem Datum den zukünftigen Durchschnitt „kennt“. Zweitens ist pos nicht verschoben: Die heutige Rendite wird mit einem Signal erzielt, das aus dem heutigen Schlusskurs berechnet wurde.

(b) In-Sample: 2.4 × √6 = 5.9; Out-of-Sample: −0.3 × √2 = −0.4. Der hohe In-Sample-Wert wurde durch die Fehler erzeugt, und deshalb ist er eingebrochen.

(c) Verwenden Sie ein rollierendes oder expandierendes Fenster und eine Verschiebung:

  • m = df.close.rolling(250).mean(); s = df.close.rolling(250).std()
  • df['z'] = (df.close - m) / s
  • df['signal'] = df.z < -1.5
  • df['pos'] = df.signal.shift(1).fillna(False).astype(int)
  • df['ret'] = df.close.pct_change() * df.pos

Einschränkungen: Das Entfernen von Look-Ahead macht den Test ehrlich, nicht profitabel; die korrigierte Regel braucht weiterhin Kosten, eine Engine mit Stops und einen neuen Out-of-Sample-Zeitraum.

Kernaussagen

  • Halten Sie wiederverwendbaren Code mit Tests in src/, schreiben Sie Versionen fest und sorgen Sie dafür, dass „alles ausführen“ den Bericht reproduziert.
  • Legen Sie Hypothese, Regeln und die Aufteilung in In-Sample und Out-of-Sample vor dem ersten Backtest fest; führen Sie Out-of-Sample einmal aus.
  • Prüfen Sie Timing, Daten, Ausführungen, Kosten und die Zahl der Versuche mit einer Checkliste; protokollieren Sie jede getestete Variante.
  • Geben Sie die Signifikanz grob als Sharpe × √Jahre an, dazu die Zahl der Varianten und die Entscheidung, einschließlich „nicht genügend Evidenz“.

Nächster Schritt

Damit ist „Python für Trader & Investoren“ abgeschlossen; der nächste Kurs, „Prop Firms, Funded Accounts & Trading als Business“, befasst sich mit Evaluierungsregeln, Drawdown-Arten und der praktischen sowie der deutschen steuerlichen Seite des Tradings als Business, wobei ein getesteter, per Skript automatisierter Prozess wie der, den Sie hier aufgebaut haben, der Ausgangspunkt ist.

Selbsttest

Beantworten Sie die Fragen und prüfen Sie dann Ihre Antworten. Sie können es so oft wiederholen, wie Sie möchten.

1. Eine Strategie zeigt Out-of-Sample über 5 Jahre eine annualisierte Sharpe Ratio von 0.9. Wie hoch ist nach der groben Regel t ≈ Sharpe × √Jahre die t-Statistik, und wie ist sie zu lesen?

2. Während einer Studie führt ein Forscher den Out-of-Sample-Zeitraum aus, sieht ein schwaches Ergebnis, ändert die Ausstiegsregel und führt den Test mit besserem Ergebnis erneut aus. Welchen Status hat das zweite Ergebnis?

3. Welche Zeile in einem Notebook führt am deutlichsten Look-Ahead-Bias ein?

Automatischer Selbsttest zur eigenen Wiederholung. Ihre Antworten werden in Ihrem Browser geprüft und von uns weder eingesehen noch bewertet. Es ist keine Prüfung und kein Abschluss.

Ihr Fortschritt

„Erledigt“ bedeutet nur, dass Sie die Lektion als abgeschlossen markiert haben. Es ist kein Test Ihres Verständnisses. Fortschritt und Notizen werden nur in diesem Browser auf diesem Gerät gespeichert — nicht in einem Konto.