20-dniowy Donchian w specu wygląda niewinnie. Agent pisze 20-barowy rolling max, backtest startuje od pierwszego wiersza pliku parquet, a przez pierwsze dwa tygodnie „20-dniowe maksimum” to po prostu bieżące maksimum z barów, które akurat są. Czwartego dnia to czterodniowe maksimum. Strategia, którą myślałeś, że testujesz, nie jest tą, która wygenerowała pierwszy tuzin filli.
Mam notebook na dziennych barach ETHUSDT, w którym Sharpe na pełnej próbie wynosi 1.4. Odetnij pierwsze 20 sesji i spada do 0.6. Zostaw te 20 i wyrzuć resztę pierwszego roku, a drukuje 3.1. Nikt nie wyciekł jutra. Strategia korzystała z przeszłości, tylko za mało jej, a raport traktował te na wpół uformowane transakcje jako dowód.
Pozwól oknu handlować, zanim się zapełni
Typowa ruina to min_periods=1. Pandas policzy rolling mean na pojedynczym barze, jeśli mu pozwolisz. Agenci robią to bez przerwy, bo NaN na górze ramki wygląda jak błąd, a jego wypełnienie sprawia, że test jednostkowy świeci na zielono.
20-dniowy target realized-vol przy dwóch obserwacjach stopy zwrotu to eksplozja wielkości pozycji. Wariancja dwóch liczb to rzut monetą, odwracasz ją i pierwsza pozycja ma kilkakrotnie większe ryzyko niż zamierzone. Z-score względem niemal zerowego odchylenia standardowego robi ten sam numer ze znakiem: strategia wygląda, jakby miała wejście jak brzytwa, które nigdy więcej się nie pojawia, gdy okno jest już uczciwe.
Wybicia są gorsze, bo wyglądają jak prawdziwa reguła. 20-barowy kanał na szóstym barze to kanał sześciobarowy. Dostajesz skupisko transakcji tuż na starcie, często w spokojnym odcinku, który nie wyzwoliłby ukończonego wskaźnika. Spokojne rynki trochę dryfują. Wąski kanał strzela. Krzywa kapitału dostaje fory, których żaden późniejszy rok nie powtarza.
Zero-fill i forward-fill wymyślają inne kłamstwo. RSI na 0 czyta się jako wyprzedanie. Brakujący ATR równy 0 rozsadza wielkość jednostki, a backtest sumiennie kupuje magazyn. Wolę, żeby NaN zabił zlecenie, niż żeby 0 je wymyśliło.
Wciąż łapię się na rysowaniu od wiersza 0, bo pusty miesiąc po lewej stronie wykresu wygląda na niedokończony. Pusty miesiąc to uczciwa część.
Przytnij krzywą kapitału, zostaw pozycję
Ten przechodzi code review. Liczysz 20-dniowe cechy jak należy, odrzucasz pierwsze 20 wierszy z rysowanej krzywej i publikujesz od 21 stycznia. Pozycja z 21 stycznia została otwarta 14 stycznia. High-water trailing stopu, licznik piramidy, gotówka po tych transakcjach z burn-in: wszystko to weszło do „czystej” próby.
Ruina to strategia paper trading, której nie da się wystartować w dacie z publikacji. Restart z pozycji flat w raportowanym starcie i zlecenia z pierwszego tygodnia się nie zgadzają. Czasem backtest jest już w transakcji, w którą system paper trading nie ma powodu wchodzić. Czasem system paper trading wchodzi, bo jego lookback jest zimny, a backtest stoi z boku, bo jego ukryty miesiąc już wziął wybicie. Dwie księgi otwarcia, jedna opublikowana data startu.
Foldy walk-forward robią to po cichu. Każde okno testowe ma ogon lookbacku, którego nie rysujesz. Pomiń symulację tego ogona i pierwsze transakcje testowe znów są transakcjami z niedokończonego okna. Zasymuluj go i raportuj tylko dni testowe, a pozycja dnia testowego zależy od filli, których nie pokazujesz. Ta druga wersja może być uprawnionym wyborem badawczym. Nazwanie pierwszego poranka foldu zimnym startem, podczas gdy trailing stop już działa z ogona, to sposób, w jaki dwaj badacze dostają dwa Sharpe'e z jednej konfiguracji.
Rób warmup w dniach kalendarzowych, gdy cecha nie jest dniem
„Daj mu 30 dni” zostawia cechę niedospecyfikowaną. Trzydzieści dni kalendarzowych na 5-minutowym Donchianie to tysiące barów poza 20-okresowym lookbackiem. Trzydzieści dni na dziennej cesze, która potrzebuje 20 sesji, jest albo za grube, albo za chude, w zależności od weekendów i dziur.
Z-score stopy funding na jednym z naszych rynków perp dostał 30-dniowy warmup, bo spec mówił 30 okresów, a ktoś przetłumaczył okresy na kalendarz. Funding tam printuje się co osiem godzin. Trzydzieści dni to około 90 rozliczeń. Trzydzieści okresów to dziesięć dni. Dodatkowe dwa miesiące burn-in akurat zawierały tydzień depegu. Wyrzucenie tego sprawiło, że okno live wyglądało spokojniej niż prawdziwa historia strategii. Ludzie zwalali na wrażliwość na datę startu. Warmup zjadł reżim.
A krypto kontra akcje sprawia, że ta sama liczba zmienia znaczenie, choć nikt nie edytował parametru. Dwadzieścia „dni” ETH obejmuje soboty. Dwadzieścia sesji akcyjnych to prawie miesiąc kalendarzowy. Skopiuj 20-dniowy lookback z notebooka na akcje na godzinowe świece perpetual i masz 20-godzinny kanał z 20-dniową nazwą. Pierwszy prawidłowy bar jest wtedy albo 20 godzin od startu, albo 20 dni od startu, jeśli jakaś późniejsza funkcja resampluje, i widziałem oba w tym samym diffie agenta.
Przypnij pierwszy znacznik czasu transakcyjnego
Warmup to wymóg danych, nie bonusowa próba. Każda cecha podaje liczbę ukończonych obserwacji, których potrzebuje, w jednostkach, w których jest liczona. Pierwszy znacznik czasu transakcyjnego to pierwszy bar, na którym wszystkie te warunki są spełnione i konto flat mogłoby wysłać zlecenie.
| Cecha | Co spec zwykle mówi | Co naprawdę musi istnieć | Cichy substytut |
|---|---|---|---|
| 20-dniowy Donchian | 20 dziennych maksimów | 20 ukończonych sesji | Running max z min_periods=1 |
| 30-dniowa realized vol | 30-dniowe okno | 30 stóp zwrotu close-to-close | Dwudniowa wariancja, odwrócona w wielkość pozycji |
| 20-printowy z-score funding | 20 dni | 20 rozliczeń funding | 20 dni kalendarzowych (~90 printów) albo 20 barów ze złego timeframe'u |
| 14-okresowy RSI na 5m | 14 okresów | 14 zamkniętych pięciominutowych barów | 14 dni albo 14 barów z lukami uzupełnionymi forward-fill |
P&L sprzed tego znacznika czasu zostaje poza track recordem. Stan sprzed tego znacznika czasu nadal może wymagać symulacji, żeby trailing stop albo cooldown były prawdziwe, gdy zegar trafia na pierwszy bar transakcyjny, ale te fille nie wchodzą do Sharpe'a, liczby transakcji ani matematyki pojemności. Potem odpal brzydki test: restart z pozycji flat w tym znaczniku czasu, z lookbackiem dostępnym wyłącznie jako dane. Jeśli zlecenia się zmienią, wysyłałeś ukryte transakcje.
Paper trading startuje według tej samej umowy. Tak samo każde okno testowe walk-forward. Jeśli wykres wygląda, jakby brakowało miesiąca, zostaw ten brak.
← Wszystkie wpisy


