Van egy kérdés, ami elől minden backtest kitér: vajon ugyanez a kód, élőben ugyanazzal a piaccal etetve, ugyanazt tette volna? Erre nem lehet további backtesteléssel válaszolni. Csak úgy lehet, ha a stratégiát élő adaton, valós végrehajtási szemantikával futtatod, majd kötésről kötésre ellenőrzöd, hogy a két világ egyetért-e. Mi ezt az ellenőrzést minden nap elvégezzük, automatikusan — és ez lett a platform messze legtermékenyebb hibavadásza.
Első nap: építsd meg a tükröt
Minden előléptetett stratégia a saját izolált élő node-jában fut, valódi tőzsdei streameket fogyasztva: élő jegyzések a kötésekhez, valódi spreadek, valódi kereskedési órák. Nincs megosztott állapot a stratégiák között (ezt a leckét a nehezebbik úton tanultuk meg — egy közös node-ban az egyik stratégia pozíciólekérdezései átszivárogtak a másikéba). Minden kötés rögzítésre kerül azzal a szignálértékkel együtt, ami kiváltotta.
Minden reggel: replay és diff
Egy napi feladat fogja az egyes stratégiák papíridőablakát, ugyanazt a kódot lefuttatja a backtest motorban ugyanarra az időszakra katalógusadaton, majd egy az egyben párosítja a kötéseket: azonos irány, azonos időbélyeg-tűrés, azonos méret. A kimenet nem korreláció és nem megérzés. Egy táblázat: párosított, csak papír, csak replay. Egy egészséges stratégia 55-ből 54 párosítottnál áll. Egy beteg stratégia pontosan megmondja, melyik kötés tért el, és mikor.
Ami elromlott, a romlás sorrendjében
- Bemelegítési kötések. Az élő node történelmi adatot töltött be az indikátorok bemelegítéséhez — az egyedi bar-kezelőt használó stratégiák pedig vidáman kereskedtek rajta. A backtestek soha nem látták ezeket a fantombelépőket. A javítás a beküldési rétegben történt, nem a stratégiákban, mert különben minden stratégia örökli a hibát.
- Szekvenciális többlábú bemelegítés. Egy keresztmetszeti stratégia egyszerre csak egy instrumentumot melegített be; minden láb üresen látta a testvéreit, és a horgony sosem inicializálódott. Élőben semmivel nem kereskedett; replayben viszont rendben kereskedett. Nulla párosított kötés — de csak a diff mondta ki hangosan.
- Tick-precizitásból fakadó összeomlási hurkok. Az élő aggTrade tickek más precizitással érkeznek, mint amit a sandbox instrumentum várt. A node egy olyan assertion miatt esett összeomlási hurokba, amit a backtest sosem tudott volna kiváltani, mert a katalógus barjai már normalizáltak.
- Újraindítási amnézia. A folyamat-újraindítások újra elsütötték a belépési logikát már meglévő pozíciókra — egy súlyozást újrarendező stratégiánál egy újraindítás csendben újrasúlyozássá vált. Élő kereskedésben ez nem paritási lábjegyzet, hanem vörös zászló, pénzzel a hátán.
Vedd észre a mintázatot: ezek közül egy sem szignálhiba. Mind végrehajtási határhiba — bemelegítés, állapot, precizitás, újraindítás. Pontosan az a hibaosztály, amelyre a backtestek szerkezetileg vakok, mert egy backtestben a backtest motor maga a végrehajtási határ.
Az aszimmetriák, amiket szándékosan megtartunk
A két világ szándékosan nem azonos. A backtest egy modellezett fél spreadet plusz négyzetgyök-hatást számol el a PnL-en belül; a papír a valós spreadet fizeti meg a kötési árban, hatásmodell nélkül. Ha a modellezett spreadet hozzáadnánk a papírhoz (vagy a valósat a backtesthez), duplán számolnánk. A paritás azt jelenti, hogy ugyanazok a döntések, ugyanazok a kötések tűréshatáron belül — nem bitre azonos PnL-t. A fegyelem java része annak ismerete, hogy mely eltérések elviek és melyek hibák.
A backtest egy hipotézis. A papírkereskedés a kísérlet. A replay-paritás pedig a laborjegyzőkönyv, ami rajtakap, amikor becsapod magad.
Ha stratégiákat futtatsz, de nem veted össze rendszeresen az élő viselkedést az újrajátszottal, van egy hibakategória, amit soha nem láttál. Nálunk nagyjából kéthetente előkerül egy — és mindegyik láthatatlan volt a backtest belsejéből nézve.
← Összes bejegyzés
