Šest tednov po izvedbi backtesta smo ga ponovili z isto kodo, konfiguracijo in časovnim obdobjem. Končno stanje kapitala je bilo drugačno. Ne bistveno, a dovolj, da se je razmerje Sharpe spremenilo z 1.31 na 1.08, obenem pa se je spremenil nabor parametrov, ki je bil videti najboljši.
Strategija se ni spremenila. Spremenili so se zgodovinski podatki. Ponudnik je popravil več dni poslov in barov, pri prvem zagonu pa nismo ohranili natančnega posnetka vhodnih podatkov. Naslednjih nekaj dni smo ugotavljali, ali je novi rezultat posledica popravka podatkov, napake v cevovodu ali raziskovalnega procesa, ki ga nismo mogli ponoviti.
Ponedeljek: ponovljeni zagon se ni ujemal
Prvi namig je bila majhna vrzel pri likvidnem promptnem paru. V našem prvotnem baru je bila najvišja vrednost 62,418. V ponovljenem zagonu je znašala 62,431. Razlika se je zdela neškodljiva, dokler nismo izsledili vstopa strategije: njen prag je bil med tema cenama. Nekaj spremenjenih barov je pomenilo drugačne signale, ti pa drugačne pozicije več dni pozneje.
Primerjali smo dnevno število poslov in ugotovili, da se je neskladje začelo na en sam datum. Nato smo primerjali surove vrstice, ki so bile podlaga za ta datum. Trenutni odgovor ponudnika je vseboval nekaj popravljenih poslov in spremenjen agregirani bar. Odgovoru, ki smo ga uporabili, ni bil priložen dnevnik sprememb.
Takšno vedenje podatkov je običajno. Borze popravljajo zapise, ponudniki zapolnjujejo vrzeli, popravljajo napačne posle in prilagajajo logiko agregiranja. Poizvedba za »januarske podatke« lahko marca vrne drugačen odgovor.
Torek: našli smo manjkajoče potrdilo
V zapisu zagona smo shranili ime ponudnika, simbol in časovno obdobje. Nismo pa shranili samega odgovora ali zgoščene vrednosti vsebine za vsako vhodno particijo. Tako smo lahko dokazali, kaj smo zahtevali, ne pa tudi, katere bajte je vrnil ponudnik.
Poiskali smo najstarejše predpomnjene datoteke, ki smo jih našli, in jih primerjali s trenutnim odgovorom. Razlika ni bila posledica prilagoditve zaradi razcepa delnic ali pretvorbe časovnega pasu. Šlo je za manjši nabor popravljenih zapisov poslov, ki so šli skozi naš gradnik barov. S tem smo ovrgli eno od razlag, vendar je bil predpomnilnik nepopoln, zato še vedno nismo mogli natančno rekonstruirati vseh prizadetih barov.
| Kaj smo zabeležili | Na katero vprašanje smo lahko odgovorili | Kaj je manjkalo |
|---|---|---|
| Ponudnik, simbol, časovno obdobje | Katero zahtevo je poslal zagon | Vsebina odgovora |
| Različica cevovoda | Katera koda je zgradila bare | Natančne vhodne vrstice |
| Časovni žig zagona | Kdaj smo izvedli opravilo | Katera revizija ponudnika je bila takrat na voljo |
Predpostavljali smo, da »ista poizvedba« pomeni »isti podatki«. Zaradi te predpostavke se je eksperiment zdel bolj ponovljiv, kot je bil v resnici.
Sreda: popravek je spremenil zgodbo
Prizadete datume smo ponovno obdelali z obema različicama razpoložljivih podatkov. Popravljeni bari so odstranili dva vstopa in premaknili en izstop za en bar. Ti trije posli so pojasnili večino spremembe razmerja Sharpe. Strategija je bila občutljiva na nekaj opazovanj blizu sprožilnega praga, čeprav je bila celotna cenovna serija na grafu videti skoraj enaka.
To ni pomenilo, da je bil prvotni rezultat zavajajoč ali da je bil popravljeni rezultat samodejno boljši. Pomenilo je, da je bilo treba trditev opredeliti: stari zagon je opisoval posnetek podatkov, ki smo ga imeli takrat, ponovljeni zagon pa trenutno zgodovino ponudnika. Enemu nismo mogli pošteno reči ponovitev drugega.
Četrtek: spremenili smo raziskovalni zapis
Novim raziskovalnim zagonom smo dodali nespremenljive posnetke vhodnih podatkov. Vsaka particija dobi zgoščeno vrednost vsebine, manifest zagona pa zabeleži vir, čas pridobitve, različico sheme, pravilnik prilagoditev in različico kode za transformacijo. Pri velikih naborih podatkov dejanske datoteke hranimo v shrambi, naslovljeni po vsebini, zato lahko enake particije delimo, ne da bi prepisali prejšnje različice.
Kadar nam pravila shranjevanja ali licenciranja ne dovoljujejo hranjenja surovih podatkov, ohranimo najzanesljivejše dokazilo, ki ga pogoji dopuščajo: zgoščene vrednosti, parametre zahtev, identifikatorje revizij vira in majhen vzorec razčlenjenih vrstic za diagnostiko. Iz zgoščene vrednosti podatkov ne moremo obnoviti, lahko pa z njo ugotovimo, kdaj zagona nista uporabila enakih bajtov.
Ponovljiv backtest potrebuje identiteto vhodnih podatkov, ne zgolj URL podatkov. Zabeležite, kaj je prispelo, kdaj je prispelo in kako so iz tega nastale vrstice, ki jih je uporabila vaša strategija.
Petek: čemu bi se naslednjič izognili
Izognili bi se primerjanju zgolj glavnih metrik. Spremenjeno razmerje Sharpe pove, da se je nekaj premaknilo, ne pa, kje je vzrok. Začnite s številom vrstic in zgoščenimi vrednostmi particij, nato poiščite prvi vhodni datum z razliko. Zatem primerjajte transformirane vrstice, signale, naročila in izvršitve, v tem vrstnem redu.
Izognili bi se tudi tihemu nadomeščanju starih podatkov s popravljeno zgodovino. Popravki so koristni, vendar morajo stari zagoni ostati povezani s svojimi prvotnimi vhodi. Nov nabor podatkov mora ustvariti nov zagon z jasno navedeno povezavo do starejšega.
Naše praktično pravilo je zdaj preprosto: če naj bi ponovljeni zagon reproduciral eksperiment, zaklenemo posnetek podatkov. Če naj bi izkoristil popravljeno zgodovino, ga označimo kot nov eksperiment. Za razumevanje te razlike smo potrebovali nekaj dni, zdaj pa je zapisana v eni vrstici manifesta zagona.
← Vse objave


