22. října 2026 · data

Znovu jsme sestavili backtest poté, co dodavatel dat změnil svou historii

Znovu jsme sestavili backtest poté, co dodavatel dat změnil svou historii

Šest týdnů po prvním backtestu jsme ho spustili znovu se stejným kódem, konfigurací a časovým rozsahem. Konečný stav kapitálu se lišil. Ne o mnoho, ale dost na to, aby se Sharpe ratio změnilo z 1.31 na 1.08 a aby jako nejlepší vypadal jiný soubor parametrů.

Strategie se nezměnila. Změnila se historická data. Dodavatel revidoval obchody a svíčky za několik dní a při prvním spuštění jsme neuchovali přesný snímek vstupních dat. Několik následujících dní jsme zjišťovali, jestli nový výsledek způsobila oprava dat, chyba v pipeline, nebo výzkumný postup, který nedokážeme zopakovat.

Pondělí: výsledky opakovaného běhu se lišily

Prvním vodítkem byla drobná mezera u likvidního spotového páru. V původních datech měla svíčka maximum 62,418. Při opakovaném běhu to bylo 62,431. Rozdíl vypadal neškodně, dokud jsme nevystopovali vstup strategie: její práh ležel mezi těmito cenami. Několik změněných svíček znamenalo jiné signály, a tím i jiné pozice o několik dní později.

Porovnali jsme denní počty obchodů a zjistili, že nesoulad začíná v jediném dni. Pak jsme porovnali nezpracované řádky, které pro tento den sloužily jako vstup. Aktuální odpověď dodavatele obsahovala několik opravených obchodů a revidovanou souhrnnou svíčku. K odpovědi, kterou jsme použili při prvním běhu, nebyl připojen žádný seznam změn.

Takto se data běžně chovají. Burzy opravují záznamy; dodavatelé doplňují chybějící údaje, opravují chybné záznamy obchodů a upravují agregační logiku. Dotaz na „lednová data“ může v březnu vrátit jiný výsledek.

Úterý: našli jsme chybějící potvrzení

V záznamu běhu jsme uchovávali název dodavatele, symbol a časový rozsah. Neuchovávali jsme samotnou odpověď ani kontrolní součet obsahu jednotlivých datových částí. Mohli jsme tedy doložit, na co jsme se zeptali, ale ne to, jaké bajty nám dodavatel vrátil.

Našli jsme nejstarší soubory v mezipaměti a porovnali je s aktuální odpovědí. Rozdíl nezpůsobila úprava kvůli rozdělení akcií ani převod časového pásma. Šlo o malý soubor opravených záznamů obchodů, které prošly naším sestavováním svíček. Jednu teorii jsme tím vyloučili, ale mezipaměť nebyla úplná, takže jsme stále nedokázali přesně rekonstruovat všechny dotčené svíčky.

Co jsme zaznamenaliNa jakou otázku to odpověděloCo chybělo
Dodavatel, symbol, časový rozsahJaký požadavek běh odeslalObsah odpovědi
Verze pipelineJaký kód sestavil svíčkyPřesné vstupní řádky
Čas spuštěníKdy jsme úlohu spustiliKterá revize dat dodavatele byla v té době dostupná

Předpokládali jsme, že „stejný dotaz“ znamená „stejná data“. Díky tomuto předpokladu vypadal experiment reprodukovatelněji, než ve skutečnosti byl.

Středa: oprava změnila celý příběh

Dotčené dny jsme znovu prošli s oběma dostupnými verzemi dat. Revidované svíčky odstranily dva vstupy a posunuly jeden výstup o jednu svíčku. Tyto tři obchody vysvětlovaly většinu změny Sharpe ratio. Strategie byla citlivá na několik pozorování blízko spouštěcího prahu, přestože celá cenová řada v grafu vypadala téměř totožně.

Neznamenalo to, že původní výsledek byl podvodný nebo že revidovaný výsledek je automaticky lepší. Znamenalo to, že jsme museli přesně vymezit, co který výsledek popisuje: starý běh zachycoval snímek dat, který jsme tehdy měli, zatímco opakovaný běh zachycoval aktuální historii dodavatele. Nemohli jsme poctivě tvrdit, že jeden běh reprodukuje druhý.

Čtvrtek: změnili jsme výzkumné záznamy

Do nových výzkumných běhů jsme přidali neměnné snímky vstupních dat. Každá datová část dostane kontrolní součet obsahu a manifest běhu zaznamená zdroj, čas získání, verzi schématu, pravidla úprav a verzi transformačního kódu. U rozsáhlých datových sad uchováváme skutečné soubory v úložišti adresovaném podle obsahu, takže lze sdílet totožné datové části, aniž bychom přepsali starší verze.

Když nám pravidla uchovávání nebo licence brání ponechat si nezpracovaná data, zachováme nejsilnější doklad, který podmínky dovolují: kontrolní součty, parametry požadavku, identifikátory revizí zdroje a malý vzorek zpracovaných řádků pro diagnostiku. Kontrolní součet data neobnoví, ale prozradí nám, jestli dva běhy zpracovaly totožné bajty.

Reprodukovatelný backtest potřebuje identifikaci vstupních dat, ne jen URL k datům. Zaznamenejte, co dorazilo, kdy to dorazilo a jak z toho vznikly řádky, které zpracovala vaše strategie.

Pátek: čemu bychom se příště vyhnuli

Vynechali bychom porovnávání jen hlavních metrik. Změna Sharpe ratio vám řekne, že se něco posunulo, ale neodhalí příčinu. Začněte počty řádků a kontrolními součty datových částí, pak najděte první rozdílný den ve vstupních datech. Potom porovnávejte transformované řádky, signály, příkazy a plnění, právě v tomto pořadí.

Také bychom se vyhnuli tichému nahrazování starých dat opravenou historií. Opravy jsou užitečné, ale staré běhy mají zůstat svázané se svými původními vstupy. Nová datová sada má vytvořit nový běh s viditelnou vazbou na ten starší.

Naše praktické pravidlo je teď jednoduché: pokud má opakovaný běh reprodukovat experiment, pevně určete snímek dat. Pokud má využít opravenou historii, označte ho jako nový experiment. Trvalo nám několik dní, než jsme tento rozdíl pochopili; v manifestu běhu se pak projevil jedním řádkem.

tržní databacktestingdatové inženýrstvíreprodukovatelnost
← Všechny články