Isti commit, iste datoteke parquet, isti računalnik, dva zagona v razmiku ene ure. Sharpe 1.34 in Sharpe 1.19. Skupni donos 41.2% in 37.8%. Število poslov 1,418 in 1,421. Krivulji kapitala sta se do zadnje izpisane decimalke ujemali 11,205 zaporednih svečk, nato pa sta se razšli.
Prve tri številke so nadležne. Zadnja pa je zanimiva, ker pove, da težava ni bila površno razpršena napaka s plavajočo vejico po celotnem teku. Na določeni svečki se je zgodilo nekaj diskretnega, vse drugo pa je bila posledica stopnjevanja. Ta zapis govori o tem, kako najti tisto svečko in kaj velikost te razlike 0.15 pomeni za vsako optimizacijo parametrov, ki ste jo kdaj izvedli.
Strategija: presečni moment na 30 perpetualnih pogodbah USDⓈ-M z največjim obsegom, 4-urna ponovna uravnotežitev, dolga pozicija v petih najboljših glede na 12-urni donos, kratka v petih najslabših, 18 mesecev zgodovine, provizije in financiranje se obračunajo za vsako nogo posebej.
Iskanje svečke, kjer se poti razidejo
Če beležite kapital za vsako svečko z največjo natančnostjo, to traja približno štiri minute. Oba zagona izvozite v CSV z (bar_index, equity, open_positions_hash), naložite oba in poiščite prvi indeks, kjer se razlikujeta. Ta skript smo že napisali za odpravljanje druge napake; samo zato se s tem nisem ukvarjal celo dopoldne.
Svečka 11,206, 2025-03-14T08:00 UTC. Kapital se je na predhodni svečki ujemal do 13 pomembnih števk. Na svečki 11,206 se zgoščeni vrednosti pozicij razlikujeta: v zagonu A smo bili dolgi SOL, v zagonu B pa AVAX. Ista smer, enaka nominalna vrednost, drug simbol. Vse, kar sledi, je posledica tega.
Zato sem izpisal vhodne podatke za razvrstitev pri tej svečki v obeh zagonih. Bili so enaki. Bajt za bajtom enaki: istih 30 simbolov, istih 30 rezultatov. Dva rezultata sta bila 0.0. Natanko nič, oba, ker pri obeh simbolih v opazovalnem obdobju ni bilo poslov v 4-urni svečki, zato je bilo razmerje zaključnih cen ena, njegov logaritem pa nič. Ne zaokroženo na nič. Nič.
Dva simbola sta bila izenačena na petem mestu. Izbrali smo pet najboljših. Kateri od obeh se je uvrstil, je bilo odvisno od vrstnega reda po razvrščanju, ta pa se ni obnašal tako, kot sem predpostavljal.
Izenačenje, nestabilno razvrščanje in stvar, ki sem jo dve leti spregledoval
Razvrščanje je potekalo prek združene agregacije, okvir, ki ji je posredoval podatke, pa je nastal z izrazom dict comprehension čez množico simbolov, ki smo jo ob vsaki svečki znova ustvarili z asinhronim pridobivanjem podatkov. Vrstni red iteriranja po množici se spreminja glede na seme zgoščevanja, Python pa za vsak proces naključno določi seme zgoščevanja nizov, razen če določite PYTHONHASHSEED. Zato se je vrstni red vrstic pred razvrščanjem med zagonoma razlikoval, nestabilno razvrščanje pri izenačenem ključu pa je izenačenje razrešilo različno.
Takšna izenačenja niso redkost. So strukturna. Kjer koli se značilnost nasiči ali omeji, ustvarite popolno enakost: svečke brez obsega ustvarijo donose, ki so natanko nič, omejeni z-rezultat se ustavi pri ±3.0, transformacija rangov z malo različnimi vrednostmi ustvari na desetine izenačenj, logični filter pa vsem, ki ga prestanejo, dodeli rezultat 1.0. V tem teku je bilo v 18 mesecih s 4-urnimi svečkami 47 svečk, na katerih so bili rezultati na meji izbora izenačeni. Tri od njih so spremenile izbrano košarico. Pri preostalih je šlo za izenačenje med dvema simboloma, ki sta bila oba že izbrana ali oba izločena.
Približno en dan sem bil prepričan, da je nalagalnik podatkov nedeterminističen, ker je to vznemirljiv odgovor. Ni bil. Nikoli ni. Šlo je za množico, izenačenje in predpostavko o stabilnosti razvrščanja, ki je ni nihče zapisal.
Zakaj so trije posli vredni 0.15 Sharpa
To je del, ob katerem ljudje ugovarjajo. Odgovor je, da je backtest z določanjem velikosti glede na delež kapitala sistem, odvisen od poti. Če za vsako nogo določimo velikost v višini 8% trenutnega kapitala, razlika v kapitalu pri svečki n pomeni razliko v vsaki nominalni vrednosti od svečke n naprej.
Prvo odstopanje samo po sebi ni veliko stalo. Nogа AVAX v zagonu B je v devetih urah izgubila 2.1%; noga SOL v zagonu A je pridobila 0.4%. Razlika v kapitalu po tem poslu: 0.21%. Malenkost. Toda od takrat naprej zagona nista več izvajala iste strategije. Velikosti pozicij so nekoliko različne, zato naletita na nekoliko različne obračune financiranja. Poleg tega sta se pozneje še dve izenačenji na meji razrešili različno, ker so rezultati, ki so ju določali, temeljili na malenkost drugačnih obstoječih pozicijah. Eno se je zgodilo 2025-03-27, dan pred šestdnevnim trendom, ki je ustvaril približno tretjino skupnega PnL zagona. Zagon A je bil v poziciji ves čas gibanja; zagon B je vstopil eno ponovno uravnotežitev pozneje.
Razlika v donosu: 3.4 točke. Razlika v Sharpovem količniku je večja, kot bi sklepali iz razlike v donosu, ker so se preurejeni posli v zagonu B prekrivali z bolj volatilnim obdobjem. Zato se je imenovalec povečal, števec pa zmanjšal. Majhen vzrok, dva ojačevalna učinka.
Če uporabljate nespremenljivo nominalno vrednost pozicij in vaši vstopi niso odvisni od trenutnih pozicij, ste precej bolj zaščiteni. Večina zanimivih strategij nima ne ene ne druge lastnosti.
Pet mest, kjer do tega dejansko pride
| Vir | Simptom | Popravek |
|---|---|---|
Nedoločeno PYTHONHASHSEED, pri katerem vrstni red iteriranja po množici ali slovarju vpliva na razvrščanje | Izenačenja se med zagoni razrešijo različno; prvo odstopanje nastopi pri določeni svečki | Določite seme; uporabite izrecni sekundarni ključ (simbol), da bodo izenačenja razrešena deterministično |
Nestabilno razvrščanje po izenačenem ključu (quicksort privzeta možnost v NumPy/pandas) | Enako kot zgoraj, vendar se ohrani tudi po določitvi semena | kind="stable" ali določite popoln ključ |
| Nenastavljen RNG pri bootstrapu, mešanju učnih/testnih podatkov ali naključnem odklonu pri sintetičnem polnjenju naročil | Odstopanje v celotnem teku, brez jasne točke razhoda | Za vsako komponento določite lastno seme in ga zabeležite v manifestu zagona |
| Vzporedno seštevanje števil s plavajočo vejico (vrstni red seštevanja je odvisen od števila niti) | Razlike v zadnjih nekaj bitih, običajno neškodljive, dokler ne prečkajo praga pri primerjavi | Pri raziskovalnih zagonih določite število niti; pri odločitvah na meji nikoli ne primerjajte števil s plavajočo vejico z == |
| Nedoločene različice knjižnic | Danes ponovljivo, novembra pa ne več | V manifest poleg zgoščene vrednosti posnetka podatkov dodajte zgoščeno vrednost datoteke zaklepa različic |
Četrta vrstica je manj pomembna, kot se ljudje bojijo, prva pa povzroča težave ves čas.
Bitna ponovljivost je orodje, ne vrlina
Determinizem potrebujete zato, da je ob spremembi ene vrstice razlika v krivulji kapitala pripisljiva prav tej vrstici. To je ves razlog. Zdaj vsak zagon agenta na Stratmill zapiše manifest z zgoščeno vrednostjo posnetka podatkov, zgoščeno vrednostjo datoteke zaklepa različic in vsemi semeni. Če ponovni zagon krivulje ne poustvari bit za bitom, je to neuspešna gradnja, ne zanimivost.
Ko pa lahko rezultate ponovite, jih namenoma naredite neponovljive. Zadevo zaženite 64-krat s 64 semeni in si oglejte razpon:
Razpon nihanja. Ista strategija, isti podatki, 64 permutacij vrstnega reda razreševanja izenačenj in polnjenja naročil z določenimi semeni. Sharpe p5 1.12, mediana 1.27, p95 1.41. Širina razpona 0.29.
Zdaj se vrnite k optimizaciji parametrov. Najboljša konfiguracija je dosegla 1.46. Konfiguracija na 40. mestu od 96 je dosegla 1.31. Razlika med njima je 0.15, kar je polovica razpona. Optimizacija teh dveh konfiguracij ni razvrstila. Iz vsake porazdelitve je vzela en vzorec in nato razvrstila vzorca.
Ta drugačen pogled je spremenil naš način izbire. Rezultat optimizacije je razvrstitev le, če so razlike med konfiguracijami večje od nihanja posamezne konfiguracije. Pri strategiji, odvisni od poti, s 1,400 posli je nihanje običajno tako veliko, da se zgornja tretjina lestvice izenači. Ko se to zgodi, izbirajte po merilih, ki jih razpon ne more prikriti: manjša pogostost trgovanja, manj parametrov, predpostavka o stroških, ki bi jo zagovarjali pred skeptikom, ali boljše vedenje v tistem delu walk-forward preverjanja, ki vam je najmanj všeč. To so resnični kriteriji za razrešitev izenačenja. Prednost 0.15 pri Sharpovem količniku to ni.
Preden vsemu temu zaupate, naredite še nekaj. Že zdaj dvakrat zaženite backtest, primerjajte kapital po posameznih svečkah in ugotovite, ali sodite med tiste z bitno enakimi rezultati ali tiste z razliko 0.15. To je petnajstminutni preizkus, ki vam pove, kolikšen del vaše raziskovalne zgodovine je meril strategijo in kolikšen seme zgoščevanja.
← Vse objave

