1. November 2026 · Forschung

Wie wärmt man einen Backtest auf, ohne den Lookback als Performance zu zählen?

Wie wärmt man einen Backtest auf, ohne den Lookback als Performance zu zählen?

Ein 20-Tage-Donchian wirkt in einer Spec harmlos. Der Agent schreibt ein 20-Bar-Rolling-Max, der Backtest startet in Zeile 1 der Parquet-Datei, und in den ersten 2 Wochen ist das „20-Tage-Hoch“ nur das laufende Maximum der Bars, die überhaupt existieren. Am Tag 4 ist es ein 4-Tage-Hoch. Die Strategie, die man zu testen glaubte, ist nicht die, die die ersten Dutzend Fills erzeugt hat.

Ich habe ein Notebook mit ETHUSDT-Tagesbars, in dem der Full-Sample-Sharpe 1.4 beträgt. Schneidet man die ersten 20 Sitzungen ab, fällt er auf 0.6. Behält man diese 20 und lässt den Rest von Jahr 1 weg, steht 3.1. Niemand hat den morgigen Tag geleakt. Die Strategie hat die Vergangenheit genutzt, nur nicht genug davon, und der Report hat diese halb fertigen Trades als Beleg gewertet.

1.4Full-Sample-Sharpe, unfertiges Fenster eingeschlossen
0.6derselbe Code nach 20 abgeschlossenen Sitzungen
3.1Sharpe, wenn man nur die Burn-in-Trades behält

Das Fenster handeln lassen, während es sich noch füllt

Der übliche Scherbenhaufen ist min_periods=1. Pandas berechnet einen Rolling Mean auf einem einzelnen Bar, wenn man es lässt. Agenten tun das ständig, weil ein NaN oben im Frame wie ein Bug wirkt und das Auffüllen den Unit-Test grün macht.

Ein 20-Tage-Realized-Vol-Target mit 2 Return-Beobachtungen ist eine Size-Explosion. Die Varianz von 2 Zahlen ist ein Münzwurf, man invertiert sie, und die erste Position ist um ein Vielfaches höher als das vorgesehene Risiko. Ein Z-Score gegen eine Standardabweichung nahe 0 macht denselben Trick mit einem Vorzeichen: Die Strategie scheint einen messerscharfen Einstieg zu haben, der nie wieder auftaucht, sobald das Fenster ehrlich ist.

Breakouts sind schlimmer, weil sie wie die echte Regel aussehen. Ein 20-Bar-Kanal auf Bar 6 ist ein 6-Bar-Kanal. Man bekommt gleich am Start einen Cluster von Trades, oft in einer ruhigen Phase, die den fertigen Indikator nicht ausgelöst hätte. Ruhige Märkte driften ein wenig. Ein enger Kanal feuert. Die Equity-Kurve bekommt einen Vorsprung, den kein späteres Jahr wiederholt.

Zero-Fill und Forward-Fill erfinden eine andere Lüge. RSI bei 0 liest sich als überverkauft. Ein fehlender ATR von 0 sprengt die Unit-Size, und der Backtest kauft brav ein Lagerhaus. Ich lasse lieber ein NaN die Order killen, als dass eine 0 eine erfindet.

Ich erwische mich immer noch dabei, ab Zeile 0 zu plotten, weil ein leerer Monat links im Chart unfertig wirkt. Der leere Monat ist der ehrliche Teil.

Die Equity-Kurve beschneiden, die Position behalten

Das hier überlebt den Code Review. Man berechnet die 20-Tage-Features sauber, wirft die ersten 20 Zeilen aus der geplotteten Kurve und veröffentlicht ab dem 21. Januar. Die Position am 21. Januar wurde am 14. Januar eröffnet. Das High-Water des Trailing Stops, der Pyramid-Count, das Cash nach diesen Burns: all das ist in die „saubere“ Sample hineinspaziert.

Der Scherbenhaufen ist eine Paper-Strategie, die sich am Datum im Write-up nicht starten lässt. Startet man zum angegebenen Start flat neu, stimmen die Orders der ersten Woche nicht überein. Manchmal ist der Backtest schon in einem Trade, den das Paper-System keinen Grund hat einzugehen. Manchmal steigt das Paper-System ein, weil sein Lookback kalt ist, und der Backtest sitzt draußen, weil sein versteckter Monat den Breakout schon genommen hat. 2 Opening Books, 1 veröffentlichtes Startdatum.

Walk-Forward-Folds tun das leise. Jedes Testfenster hat einen Lookback-Schwanz, den man nicht plottet. Überspringt man die Simulation dieses Schwanzes, sind die ersten Test-Trades wieder Trades mit unfertigem Fenster. Simuliert man ihn und reportet nur die Testtage, ist die Position des Testtages bedingt durch Fills, die man nicht zeigt. Diese zweite Variante kann eine legitime Research-Entscheidung sein. Den ersten Morgen des Folds als Cold Start zu bezeichnen, während ein Trailing Stop aus dem Schwanz schon live ist, ist der Weg, wie 2 Researcher aus 1 Config 2 Sharpes ziehen.

Wenn ein Neustart von Flat zum veröffentlichten Startdatum das P&L ändert, steckt der Warmup in der Track Record. Die Lookback-Daten dürfen vorhanden sein. Die Lookback-Trades dürfen es nicht.

In Kalendertagen aufwärmen, wenn das Feature kein Tag ist

„Gib ihm 30 Tage“ lässt das Feature unterspezifiziert. 30 Kalendertage auf einem 5-Minuten-Donchian sind Tausende von Bars über einen 20-Perioden-Lookback hinaus. 30 Tage auf einem Daily-Feature, das 20 Sitzungen braucht, sind entweder zu fett oder zu dünn, je nach Wochenenden und Löchern.

Ein Funding-Rate-Z-Score auf einem unserer Perp-Venues bekam einen 30-Tage-Warmup, weil die Spec 30 Perioden sagte und jemand Perioden in Kalender übersetzt hat. Funding wird dort alle 8 Stunden gedruckt. 30 Tage sind etwa 90 Settlements. 30 Perioden sind 10 Tage. Die extra 2 Monate Burn-in enthielten zufällig eine Depeg-Woche. Sie wegzulassen ließ das Live-Fenster ruhiger wirken als die echte Historie der Strategie. Die Leute haben Start-Date-Sensitivität die Schuld gegeben. Der Warmup hatte das Regime gefressen.

Und Krypto versus Equity lässt dieselbe Zahl ihre Bedeutung ändern, ohne dass jemand einen Parameter editiert. 20 „Tage“ ETH enthalten Samstage. 20 Equity-Sitzungen sind fast ein Kalendermonat. Kopiert man einen 20-Tage-Lookback aus einem Aktien-Notebook auf stündliche Perpetual-Kerzen, hat man einen 20-Stunden-Kanal mit einem 20-Tage-Namen. Der erste gültige Bar ist dann entweder 20 Stunden drin oder 20 Tage drin, wenn eine spätere Funktion resampelt, und ich habe beides im selben Agent-Diff gesehen.

Den ersten handelbaren Zeitstempel festnageln

Der Warmup ist eine Datenanforderung, kein Bonus-Sample. Jedes Feature nennt die Zahl der abgeschlossenen Observations, die es braucht, in den Einheiten, in denen es berechnet wird. Der erste handelbare Zeitstempel ist der erste Bar, an dem all das zutrifft und ein Flat-Konto eine Order hätte senden dürfen.

FeatureWas die Spec üblicherweise sagtWas tatsächlich vorhanden sein mussStiller Ersatz
20-Tage-Donchian20 Tageshochs20 abgeschlossene SitzungenRunning Max mit min_periods=1
30-Tage-Realized-Vol30-Tage-Fenster30 Close-to-Close-Returns2-Tage-Varianz, invertiert in die Size
20-Print-Funding-Z-Score20 Tage20 Funding-Settlements20 Kalendertage (~90 Prints), oder 20 Bars des falschen Timeframes
14-Perioden-RSI auf 5m14 Perioden14 geschlossene 5-Minuten-Bars14 Tage, oder 14 Bars mit Forward-Fill der Lücken

P&L vor diesem Zeitstempel bleibt draußen aus der Track Record. State vor diesem Zeitstempel muss möglicherweise trotzdem simuliert werden, damit ein Trailing Stop oder ein Cooldown real ist, wenn die Uhr den ersten handelbaren Bar trifft, aber diese Fills gehören nicht in den Sharpe, die Trade-Count oder die Capacity-Rechnung. Dann der hässliche Check: Neustart von Flat zu diesem Zeitstempel, mit dem Lookback nur als Daten verfügbar. Wenn sich die Orders ändern, hat man versteckte Trades ausgeliefert.

Paper Trading startet auf demselben Contract. Jedes Walk-Forward-Testfenster ebenfalls. Wenn der Chart wirkt, als fehle ein Monat, lass ihn fehlen.

BacktestingData EngineeringWalk-ForwardAI-AgentenPaper Trading
← Alle Beiträge