28 października 2026 · opcje

Sygnał był trafny. Nasz backtest opcji kupił niewłaściwy termin wygaśnięcia.

Sygnał był trafny. Nasz backtest opcji kupił niewłaściwy termin wygaśnięcia.

We wtorek o 10:07 nasz agent badawczy wykrył krótkoterminowy układ wzrostowy na indeksowym ETF-ie. Sygnał bazowy był typowy: cena wróciła powyżej średniej z 20 barów, zmienność zrealizowana malała, a na następną sesję zaplanowano publikację danych makroekonomicznych. Proponowana transakcja to spread call z terminem wygaśnięcia za około dwa tygodnie.

Backtest uznał tę transakcję za atrakcyjną. Strategia paper jej nie złożyła. Gdy porównaliśmy zlecenia, znaczniki czasu sygnałów się zgadzały, a ceny instrumentu bazowego różniły się o zaledwie kilka centów. Różniły się kontrakty: backtest kupił opcję z piątkowym terminem wygaśnięcia, która wyglądała najlepiej w historycznym łańcuchu opcji; proces paper wybrał kolejny notowany termin wygaśnięcia, tydzień później.

Rozbieżność wynikała z połączenia kalendarzy. Traktowaliśmy „dni do wygaśnięcia” jako właściwość daty, a następnie wybieraliśmy kontrakt, którego termin wygaśnięcia był najbliższy wartości docelowej. W danych historycznych kalendarz terminów wygaśnięcia zawierał opcję tygodniową, wprowadzoną do obrotu dopiero po testowanej dacie. Backtest wykorzystał kontrakt z przyszłości, jak gdyby było to nieszkodliwe uproszczenie.

Najpierw podejrzewaliśmy błąd strefy czasowej. Daty wygaśnięcia opcji szczególnie łatwo go wywołują: sesja rynkowa kończy się w Nowym Jorku, znaczniki czasu giełd mogą być zapisane w UTC, a data o północy może przesunąć się, gdy potok danych nieostrożnie zmieni jej typ. Sprawdziliśmy to. Znaczniki czasu były prawidłowe. Tego wtorku kontrakt po prostu nie istniał w historycznym zbiorze instrumentów.

Pierwsza lekcja była taka: historyczny łańcuch opcji wymaga zbioru notowanych kontraktów ustalonego na dany moment. Data wygaśnięcia kontraktu mówi, kiedy on wygasa. Nie mówi, kiedy został wprowadzony do obrotu, od kiedy można było nim handlować ani czy system mógł go wtedy wybrać.

Przebudowaliśmy etap wyboru tak, by uwzględniał informacje dostępne w chwili podjęcia decyzji. Dla każdego kandydującego kontraktu wymagaliśmy znacznika czasu wprowadzenia do obrotu nie późniejszego niż chwila decyzji, prawidłowego kwotowania nie starszego niż nasz próg aktualności oraz sesji rynkowej, podczas której strategia mogła złożyć zlecenie. Zapisywaliśmy też zbiór kandydatów przed ich rankingiem. Ten ostatni krok miał znaczenie, bo stary backtest zachowywał tylko zwycięski kontrakt; nie mogliśmy sprawdzić, czy porównał pięć kwalifikujących się kontraktów, czy po cichu wybrał jeden z kalendarza, który jeszcze nie istniał.

10:07czas podjęcia decyzji przez sygnał
1 tydzieńrozbieżność terminu wygaśnięcia
0kwalifikujących się historycznych notowań wybranego kontraktu

Następnie przyjrzeliśmy się kwotowaniu użytemu do wyceny spreadu. Backtest niezależnie pobierał najnowsze kwotowanie każdej nogi. Ask calla pochodził z 10:06:58, a bid krótkiego calla z 10:04:11. Według ogólnych zasad dotyczących danych oba były wystarczająco aktualne, ale w międzyczasie rynek się zmienił. Midpoint spreadu wyliczony z niesynchronicznych nóg może opisywać rynek, który nigdy nie istniał.

Zmieniliśmy regułę kwotowań: znaczniki czasu obu nóg muszą dzielić najwyżej 2 sekundy, a kwotowania z przekroczonym spreadem lub zerową wielkością zlecenia są odrzucane. Zmniejszyło to liczbę użytecznych obserwacji historycznych. Pozostałe wyceny stały się jednak bardziej wiarygodne. Gdy nie było zsynchronizowanego kwotowania, oznaczaliśmy kandydujący kontrakt jako niedostępny, zamiast uzupełniać lukę nieaktualną ceną.

Potem przyszła kolej na regułę rankingu. Agent wybierał termin wygaśnięcia z najniższym kwotowanym kosztem spreadu. Brzmi rozsądnie, dopóki spread jest kwotowany na 1 kontrakt, a kwotowanie jest nieaktualne. Jasno określiliśmy cel: maksymalizować oczekiwany zysk na jednostkę zdefiniowanego ryzyka wśród kontraktów spełniających minimalne wymagania dotyczące wielkości kwotowania, jego aktualności i notowania. W tym przykładzie najbliższy kwalifikujący się termin wygaśnięcia miał kwotowany spread o szerokości $0.42 dla obu nóg, a późniejszy termin — $0.31. Tańszy na pozór kontrakt miał tylko 1 kontrakt widoczny po krótkiej stronie.

KandydatCzy termin wygaśnięcia był wtedy dostępny?Wiek kwotowaniaWidoczna wielkość po krótkiej stronieDecyzja
Piątek, termin tygodniowyNieNie dotyczyNie dotyczyOdrzuć
Kolejny piątekTak1.4 sekundy18 kontraktówKwalifikuje się
Trzeci piątekTak9.8 sekundy1 kontraktOdrzuć jako nieaktualny i mało płynny

Odtworzyliśmy tę sytuację, stosując nowe reguły. Backtest wybrał teraz ten sam termin wygaśnięcia co strategia paper i zapisał powody odrzucenia pozostałych kontraktów. Cena wejścia w spread była o $0.11 gorsza niż pierwotna historyczna cena realizacji. Nie oznaczało to, że strategia nie miała wartości; oznaczało, że wcześniejszy wynik uwzględniał wybór transakcji, którego proces live nie mógł odtworzyć.

Drobna niedogodność: formaty symboli giełdowych sprawiają, że błędy terminów wygaśnięcia wyglądają jak problemy z jakością danych. Znaleźliśmy tygodniowy kod jednego dostawcy, który różnił się jednym znakiem od kodu miesięcznego. W dziennikach audytowych nadal przechowuję surowy symbol obok znormalizowanego klucza kontraktu. To mało eleganckie, ale uchroniło nas przed zbyt pochopnym zaufaniem do schludnego połączenia danych.

Jeśli budujesz backtest opcji, zapisuj pełny zbiór kandydatów przy każdej decyzji, wraz ze statusem notowania każdego kontraktu, znacznikami czasu kwotowań, ich wielkością i powodem odrzucenia. Następnie zdefiniuj wybór kontraktu jako deterministyczną funkcję tego zrzutu danych. Wybór terminu wygaśnięcia jest częścią strategii. Jeśli backtest widzi kontrakt niedostępny dla strategii paper, porównanie sygnałów zaczyna się dopiero wtedy, gdy wynik już się zmienił.

backtestowanie opcjiwybór terminu wygaśnięciadane point-in-timemodelowanie realizacji zleceń
← Wszystkie wpisy