Rynki predykcyjne wyglądają na najłatwiejszą rzecz na świecie do backtestowania. Cena mieści się w przedziale [0, 1]. Wypłata to dolar albo nic. Bez dźwigni, finansowania, bazy ani dziwactw kontraktów perpetual o 00:00 UTC. Mieliśmy już backtester obsługujący kontrakty perpetual na kryptowaluty, z opłatami, finansowaniem i wpływem na cenę. Plan zakładał, że poświęcimy dwa dni na jego dostosowanie, a potem zaczniemy generować strategie.
Zajęło nam to osiem dni. Oto dziennik, mniej więcej chronologicznie — łącznie z dniem, w którym krzywa kapitału wyglądała niesamowicie i rzeczywiście taka była.
Dzień 1: adapter, który miał być banalny
Początkowe odwzorowanie było jeden do jednego i wydawało się proste. Rynek to instrument. Cena YES to cena. Kupno YES oznacza pozycję długą, kupno NO — krótką. Rozliczenie to wymuszone zamknięcie po 1.00 albo 0.00. Wystarczy podać godzinowy szereg cen do tej samej pętli zdarzeń i gotowe.
To odwzorowanie wytrzymało kontakt z prawdziwymi danymi przez jakieś dziewięćdziesiąt minut. Pierwszy problem dotyczył szeregu stóp zwrotu. Cała nasza warstwa ryzyka — dobór wielkości pozycji, targetowanie zmienności, raportowanie Sharpe'a — zakładała logarytmiczne stopy zwrotu z instrumentu, który istnieje bez końca. Rynek, którego cena spada z 0.04 do 0.00, ma niezdefiniowaną logarytmiczną stopę zwrotu i określoną całkowitą stratę. A rynek wyceniony na 0.04 na trzy dni przed rozliczeniem to zupełnie inny obiekt niż rynek wyceniony na 0.04 na cztery minuty przed nim, choć w obu wierszach widnieje 0.04.
Przebudowaliśmy więc cały szereg, używając czasu do rozliczenia zamiast czasu zegarowego, i zaczęliśmy traktować PnL jako wartość końcową, a nie wycenianą na bieżąco. To była słuszna decyzja, która unieważniła każdy zależny od niej fragment kodu raportującego.
Dzień 2: wzór opłaty jest strategią
Na Kalshi opłata transakcyjna nie jest potrąceniem wyrażonym w punktach bazowych. Zależy kwadratowo od ceny: w przybliżeniu 0.07 × contracts × P × (1−P), przy czym na poziomie zlecenia jest zaokrąglana w górę do centa. Oznacza to, że opłata jest najwyższa dokładnie tam, gdzie rynek przypominający rzut monetą jest najciekawszy, a przy skrajnych cenach niemal zerowa.
| Cena | Opłata za kontrakt | Wymagana przewaga (pkt proc. prawdopodobieństwa) | Opłata jako % stawki |
|---|---|---|---|
| 5¢ | 0.33¢ | 0.33 | 6.7% |
| 10¢ | 0.63¢ | 0.63 | 6.3% |
| 25¢ | 1.31¢ | 1.31 | 5.3% |
| 50¢ | 1.75¢ | 1.75 | 3.5% |
| 75¢ | 1.31¢ | 1.31 | 1.8% |
| 90¢ | 0.63¢ | 0.63 | 0.7% |
| 95¢ | 0.33¢ | 0.33 | 0.35% |
Trzecią kolumnę potraktuj jako najważniejszą: aby wyjść na zero przy kupnie po 50¢ i utrzymaniu pozycji do rozliczenia, twoja ocena prawdopodobieństwa musi przewyższać rynkową o 1.75 punktu. Nie o 1.75 procenta w ujęciu względnym, lecz bezwzględnie. Jeśli zamkniesz pozycję przed rozliczeniem, zamiast trzymać ją do końca, zapłacisz tę opłatę dwukrotnie, a do tego spread.
CLOB Polymarket historycznie miał zupełnie inną strukturę opłat: sama transakcja kosztowała niewiele, a większość kosztu wynikała ze spreadu i głębokości rynku. Ta sama logika strategii ma więc zupełnie inną ekonomikę zależnie od platformy, a każde porównanie między platformami oparte na jednym modelu opłat jest fikcją. Teraz używamy funkcji opłat przypisanej do każdej platformy, a nie pojedynczej wartości.
Jeśli czytasz tylko jeden wiersz raportu z backtestu rynku predykcyjnego, niech będzie to wiersz z opłatą wyrażoną w punktach prawdopodobieństwa. Strategia z deklarowaną przewagą prognostyczną 1.2 punktu na rynkach wycenionych na 50¢ przynosi straty na Kalshi, zanim uwzględni się choćby jeden inny koszt. Ta informacja powinna być widoczna na pierwszej stronie, a nie wymagać samodzielnego wyliczenia przez czytelnika.
Dzień 3: księga zleceń jest schodkowa i płytka
Nasz model wpływu na cenę był funkcją pierwiastkową skalibrowaną na księgach zleceń kontraktów perpetual na BTC. Tu ma zły kształt. Przy kroku ceny 1¢ dla instrumentu o wartości $1 w całej księdze jest tylko 99 możliwych poziomów cen, a na rynku o średniej płynności na najlepszym poziomie może czekać kilkaset kontraktów, po czym pojawia się luka.
Oto migawka z rynku danych ekonomicznych, który próbkowaliśmy — strona YES, około 30 godzin przed rozliczeniem:
| Poziom | Wolumen (kontrakty) | Skumulowany koszt zakupu |
|---|---|---|
| 42¢ | 310 | 310 @ śr. 42.0¢ |
| 43¢ | 85 | 395 @ śr. 42.2¢ |
| 45¢ | 140 | 535 @ śr. 42.9¢ |
| 49¢ | 600 | 1,135 @ śr. 46.1¢ |
Zlecenie na 1,000 kontraktów — ryzyko o wartości pięciuset dolarów, drobiazg na rynku kryptowalut — przesuwa efektywną cenę o cztery centy. To ponad dwa razy więcej niż opłata. Nie da się tu dopasować gładkiej funkcji; trzeba przechodzić przez kolejne poziomy księgi albo zmyślać. Usunęliśmy model sqrt dla tej klasy aktywów i napisaliśmy dosłowny algorytm przechodzący po księdze. Jest wolniejszy, ale poprawny.
W pewnym momencie przyłapałem się na irytacji, że te rynki są „zbyt małe, by miało to znaczenie”. Są małe, bo wyceniają pojedyncze pytanie o rzeczywisty świat z określonym terminem, a liczba osób mających opinię o początkowych wnioskach o zasiłek dla bezrobotnych w USA w środę jest ograniczona. Ta wielkość jest rynkiem. Narzekanie na nią przypomina narzekanie, że przy stole pokerowym mieszczą się tylko dziewięć osób.
Dzień 4: dzień, w którym krzywa kapitału była piękna
Sharpe 4.1 na 1,400 rynkach. Gładka krzywa. Każdy badacz powinien poczuć ścisk w żołądku na ten widok — ja poczułem go w końcu, jakieś czterdzieści minut po tym, jak zrobiłem zrzut ekranu.
Błąd tkwił w resamplerze. Historia cen na niepłynnych rynkach ma nieregularne znaczniki czasu, więc przekształciliśmy ją do równomiernej siatki godzinowej. Ostatni punkt każdej zarchiwizowanej serii to wartość rozliczenia: 1.00 albo 0.00. Przy ponownym próbkowaniu użyliśmy interpolacji najbliższego sąsiada bez ograniczenia kierunku, więc na każdym rynku, na którym ostatnia transakcja odbyła się kilka godzin przed rozliczeniem, wartość rozliczenia rozprzestrzeniała się wstecz przez całą lukę. Model odczytywał jutrzejszą odpowiedź w dzisiejszym wierszu — dokładnie na tych niepłynnych rynkach, na których mógł zwiększać pozycję bez napotykania limitów głębokości.
Interpolacja najbliższego sąsiada sprawdza się w przypadku instrumentu ciągłego. Gdy ostatnia obserwacja instrumentu jest prawdą, działa jak maszyna do lookahead bias. Teraz wymuszamy, by każda imputacja przebiegała wyłącznie naprzód, a wiersz rozliczenia był oznaczony i wykluczony z obliczania cech. Ten warunek ma dziewięć wierszy i jest najcenniejszym kodem, jaki napisaliśmy przez cały tydzień.
Dni 5–6: 1,412 rynków, mniej więcej 180 zakładów
Wielkość próby na rynkach predykcyjnych to pułapka o przyjaznym obliczu. Rozliczasz 1,412 rynków, wydaje ci się, że masz 1,412 obserwacji, i odpowiednio obliczasz statystykę t. Ale czternaście meczów NFL w tę samą niedzielę zależy od tego samego układu pogodowego, publikacji raportów o kontuzjach i wspólnego przepływu zleceń graczy. Pięćdziesiąt jeden rynków wyborczych na poziomie stanów zależy od jednego ogólnokrajowego przesunięcia poparcia. „Czy X wydarzy się do 31 marca” i „czy X wydarzy się do 30 czerwca” to ten sam zakład z różnymi terminami wygaśnięcia; rozstrzygają się jednocześnie.
Pogrupowaliśmy rynki według źródła zdarzenia i daty rozstrzygnięcia. Otrzymaliśmy efektywną liczbę niezależnych obserwacji bliską 180. To za mało, by przy analizowanych przez nas wielkościach efektu odróżnić rzeczywistą przewagę od szumu. Nie naprawi tego bootstrap dla każdego rynku z osobna, bo bootstrap musi losować klastry, a nie wiersze. Błędne podejście po cichu zawyża istotność dwu- lub trzykrotnie.
Dzień 7: rozliczenie również ma rozkład prawdopodobieństwa
Oto rzeczy, których w ogóle nie uwzględniliśmy w modelu, a o których przekonaliśmy się na własnej skórze:
- Wcześniejsze rozstrzygnięcie. Rynek z terminem „do 31 grudnia” może zostać rozstrzygnięty już 4 sierpnia, gdy zdarzenie faktycznie nastąpi. Kapitał wraca wcześniej, a okres utrzymania pozycji nigdy nie odpowiadał temu, co sugerowała nazwa kontraktu.
- Spory. Rynki rozstrzygane przez wyrocznię mają okno na zakwestionowanie wyniku. Pozycja może pozostawać nierozstrzygnięta przez kilka dni po zdarzeniu, a w nielicznych przypadkach wynik zmienia się wbrew oczywistej interpretacji.
- Unieważnienia. Niejednoznaczne dane źródłowe mogą doprowadzić do anulowania rynku i zwrotu stawek wszystkim uczestnikom. W naszej próbie dotyczyło to mniej niż 1% rynków, ale przypadki te skupiały się dokładnie wokół niejasnych pytań, które model uznaje za błędnie wycenione.
- Zablokowanie kapitału. Przewaga 3 punktów zrealizowana w 90 dni i przewaga 3 punktów zrealizowana w 6 godzin nie są porównywalne. Backtest raportujący całkowitą przewagę bez mianownika uwzględniającego czas zaangażowania kapitału zawsze będzie faworyzować tę wolniejszą.
Dodaliśmy do symulatora koszt utrzymania pozycji i losowe przesunięcie daty rozliczenia. Żadne z tych rozwiązań nie jest precyzyjne. Oba są lepsze od niejawnego założenia, że rozliczenie nastąpi dokładnie w podanym dniu i z całkowitą pewnością.
Dzień 8: co byśmy pominęli, a od czego zaczęli
- Całkowicie pomińmy szkielet oparty na stopach zwrotu. Nie dostosowuj warstwy ryzyka targetującej zmienność do instrumentu z końcową wypłatą. Napisz warstwę doboru wielkości zakładu, operującą prawdopodobieństwem i stawką. Straciliśmy dwa dni, próbując dopasować starą warstwę.
- Zbudujmy funkcję opłat przed strategią. Dla każdej platformy, na której planujesz handlować, wydrukuj krzywą przewagi potrzebnej do wyjścia na zero i powieś ją nad biurkiem. Odrzuci mniej więcej połowę pomysłów, zanim zdążą kosztować cię jedno uruchomienie backtestu.
- Od pierwszego dnia przechodźmy po księdze zleceń. Każdy parametryczny model wpływu na cenę przeniesiony z rynku ciągłego będzie błędny w sposób korzystny dla ciebie.
- Najpierw grupujmy, potem liczmy. Ustal klucz grupowania dla efektywnej wielkości próby w tym samym czasie, w którym ustalasz uniwersum, a nie dopiero wtedy, gdy masz już Sharpe'a, który ci się podoba.
- Wymuś właściwy kierunek imputacji. Jeden warunek przy każdym łączeniu. Jeśli seria kończy się wartością stanowiącą prawdę, z definicji traktuj imputację wstecz jako błąd, zamiast liczyć na to, że ktoś zauważy go podczas przeglądu kodu.
Te osiem dni było tego warte, głównie dlatego, że rynki predykcyjne usuwają niejednoznaczności, przez które tak łatwo oszukać samego siebie w backtestach kryptowalut. Nie ma stopy finansowania, którą można zbyć machnięciem ręki, ani konwencji ceny mark, o którą można się spierać. Jest tylko pytanie, termin i odpowiedź. Gdy backtest na tych rynkach jest błędny, można wskazać konkretny powód.
← Wszystkie wpisy

