Tas pats commit, tie paši parquet faili, tā pati mašīna, divi palaišanas mēģinājumi ar stundas starpību. Sharpe 1.34 un Sharpe 1.19. Kopējā atdeve 41.2% un 37.8%. Darījumu skaits 1,418 un 1,421. Un abas kapitāla līknes sakrita līdz katrai izvadītajai decimāldaļai 11,205 joslas pēc kārtas, pirms tās pašķīrās.
Pirmie trīs skaitļi kaitina. Pēdējais ir interesants, jo tas liecina, ka problēma nav pavirša peldošā komata kļūda, kas izkliedēta pa visu izpildi. Kādā konkrētā joslā notika diskrēta izmaiņa, un viss turpmākais bija tās kumulatīvās sekas. Šajā rakstā aplūkosim, kā atrast šo joslu un ko šīs 0.15 lielums nozīmē katrai parametru pārbaudei, ko jebkad esat veikuši.
Stratēģija: šķērsgriezuma momentum stratēģija 30 USDⓈ-M perpetual līgumiem ar lielāko tirdzniecības apjomu, pārbalansēšana ik pēc 4 stundām, long pozīcija piecos aktīvos ar lielāko 12 stundu atdevi, short pozīcija piecos ar mazāko atdevi, 18 mēnešu vēsture, komisijas un finansējuma maksa par katru pozīcijas pusi.
Meklējam joslu, kurā izpildes ceļi šķiras
Ja reģistrējat kapitālu katrā joslā ar pilnu precizitāti, tas aizņem apmēram 4 minūtes. Izvadiet abas izpildes uz CSV ar (bar_index, equity, open_positions_hash), ielādējiet abas un atrodiet pirmo indeksu, kurā tās atšķiras. Mums šis skripts jau bija uzrakstīts citas kļūdas dēļ; tikai tāpēc vien šim uzdevumam nepatērēju visu rītu.
Josla 11,206, 2025-03-14T08:00 UTC. Iepriekšējā joslā kapitāls bija identisks līdz 13 zīmīgajiem cipariem. Joslā 11,206 atšķiras pozīciju jaucējvērtības: izpildē A long SOL, izpildē B long AVAX. Viena puse, tāds pats nomināls, cits simbols. Viss pēc tam izriet no šīs atšķirības.
Tad abās izpildēs izvadīju šīs joslas rangēšanas ievaddatus. Tie bija identiski. Baitu pa baitam identiski, tie paši 30 simboli, tie paši 30 rezultāti. Diviem rezultātiem bija 0.0. Tieši nulle, abiem, jo abiem aktīviem aplūkotajā periodā bija 4 stundu svece bez darījumiem, tāpēc close pret close attiecība bija viens, bet logaritms — nulle. Nevis noapaļojot līdz nullei. Nulle.
Divi aktīvi dalīja piekto vietu rangā. Atlase paņēma piecus labākos. Tas, kurš no abiem iekļuva, bija atkarīgs no tā, kādā secībā tos atstāja kārtošana, un kārtošana nedarbojās tā, kā biju pieņēmis.
Vienāds rezultāts, nestabila kārtošana un lieta, ko divus gadus ignorēju
Rangēšana notika pēc grupētas agregācijas, bet tai padotais datu rāmis tika veidots ar vārdnīcas izteiksmi, kas iterēja pa simbolu kopu. Šī kopa tika veidota no jauna katrā joslā, izmantojot asinhronu datu ielādi. Kopa maina iterācijas secību atkarībā no jaucējvērtības sēklas, un Python katrā procesā nejaušina virkņu jaucējvērtības sēklu, ja vien nenofiksējat PYTHONHASHSEED. Tāpēc rindu secība pirms kārtošanas katrā izpildē atšķīrās, un nestabila kārtošana vienādu vērtību gadījumā šo vienādību atrisināja atšķirīgi.
Šādi vienādi rezultāti nav rets izņēmums. Tie ir sistēmiski. Ikreiz, kad kāda pazīme sasniedz augšējo vai apakšējo robežu, rodas precīza vienādība: sveces bez apjoma dod precīzi nulles atdevi, ierobežots z rezultāts tiek fiksēts pie ±3.0, rangēšanas transformācija ar nedaudzām atšķirīgām vērtībām rada desmitiem vienādu rezultātu, bet Būla filtrs visam, kas tam atbilst, piešķir 1.0. Šajā izpildē 18 mēnešu periodā ar 4 stundu svecēm 47 joslās atlases robežā bija vienādi rezultāti. Trijās no tām mainījās izvēlētais aktīvu grozs. Pārējās vienādie rezultāti bija diviem aktīviem, kas abi jau bija atlasīti vai abi nebija atlasīti.
Apmēram dienu biju pārliecināts, ka nedeterministisks ir datu ielādētājs, jo tā būtu aizraujošākā atbilde. Tā nebija. Tā nekad nav. Tā bija kopa, vienādi rezultāti un pieņēmums par kārtošanas stabilitāti, ko neviens nebija pierakstījis.
Kāpēc 3 darījumi ir 0.15 Sharpe vērti
Šai daļai cilvēki mēdz iebilst. Atbilde ir tāda, ka backtests ar pozīcijas lieluma noteikšanu kā daļu no kapitāla ir no iepriekšējā ceļa atkarīga sistēma. Ja katras pozīcijas puses lielums ir 8% no pašreizējā kapitāla, tad atšķirīgs kapitāls joslā n nozīmē atšķirīgu nominālu katrā darījumā, sākot no joslas n uz priekšu.
Pirmā atšķirība pati par sevi izmaksāja maz. Izpildes B AVAX pozīcija deviņās stundās zaudēja 2.1%; izpildes A SOL pozīcija guva 0.4%. Kapitāla atšķirība pēc šī darījuma: 0.21%. Sīkums. Taču no šī brīža abas izpildes vairs nav viena un tā pati stratēģija. To pozīciju lielumi nedaudz atšķiras, tāpēc atšķiras arī uzkrātais finansējums, un vēl divās vēlākās robežsituācijās atšķirīgi atrisinājās vienādi rezultāti, jo tos noteica rezultāti, kas tagad balstījās uz mazliet atšķirīgām turētajām pozīcijām. Viena no šīm situācijām bija 2025-03-27, dienu pirms sešu dienu tendences, kas veidoja aptuveni trešdaļu no izpildes kopējās peļņas un zaudējumiem. Izpilde A piedalījās visā kustībā; izpilde B ieņēma pozīciju vienu pārbalansēšanu vēlāk.
Atdeves atšķirība: 3.4 procentpunkti. Sharpe atšķirība ir lielāka, nekā liecina atdeves atšķirība, jo izpildē B pārkārtotie darījumi pārklājās ar svārstīgāku periodu, tāpēc saucējs pieauga, bet skaitītājs saruka. Neliels cēlonis, divi pastiprinātāji.
Ja jūsu pozīciju nomināls ir fiksēts un ieejas darījumi nav atkarīgi no pašreizējām pozīcijām, šī ietekme ir daudz mazāka. Taču lielākā daļa interesanto stratēģiju nav šādas.
Piecas vietas, kur tas patiesībā notiek
| Avots | Pazīme | Risinājums |
|---|---|---|
Nenofiksēta PYTHONHASHSEED sēkla, kopas/vārdnīcas iterācijas secība ietekmē kārtošanu | Vienādi rezultāti starp izpildēm tiek atrisināti atšķirīgi; pirmā atšķirība rodas konkrētā joslā | Nofiksējiet sēklu; kārtojiet pēc skaidri norādītas sekundārās atslēgas (simbola), lai vienādie rezultāti vienmēr tiktu atrisināti vienādi |
Nestabila kārtošana pēc atslēgas ar vienādām vērtībām (quicksort noklusējums NumPy/pandas) | Tas pats, kas iepriekš, bet problēma saglabājas arī pēc sēklas fiksēšanas | kind="stable", vai izveidojiet pilnīgu atslēgu |
| Bez sēklas palaists RNG sāknēšanas izlasē, train/test sajaukšanā vai sintētiskā izpildes cenas svārstībā | Atšķirības izplatās pa visu izpildi, nav skaidra atšķirības punkta | Katrai komponentei norādiet atsevišķu sēklu un reģistrējiet to izpildes manifestā |
| Peldošā komata skaitļu paralēla summēšana (summa atkarīga no pavedienu skaita un secības) | Atšķiras daži pēdējie biti; parasti nekaitīgi, līdz tas ietekmē sliekšņa salīdzinājumu | Pētniecības izpildēm fiksējiet pavedienu skaitu; lēmumu sliekšņa tuvumā nekad nesalīdziniet peldošā komata skaitļus ar == |
| Nenofiksētas bibliotēku versijas | Šodien reproducējams, novembrī vairs ne | Manifestā līdzās datu momentuzņēmuma jaucējvērtībai iekļaujiet lockfile jaucējvērtību |
Ceturtā rinda nav tik bieži svarīga, kā cilvēki baidās, bet pirmā sagādā problēmas nepārtraukti.
Bitu līmenī reproducējama izpilde ir rīks, nevis pašmērķis
Determinisms ir vajadzīgs, lai pēc vienas koda rindas maiņas varētu attiecināt kapitāla līknes izmaiņu tieši uz šo rindu. Tas ir viss. Tagad katra Stratmill aģenta izpilde saglabā manifestu ar datu momentuzņēmuma jaucējvērtību, lockfile jaucējvērtību un katru sēklu; atkārtota izpilde, kas bitu līmenī neatkārto iepriekšējo līkni, ir neveiksmīga būve, nevis kuriozs.
Taču, tiklīdz spējat rezultātu reproducēt, apzināti izjauciet šo determinismu. Palaidiet stratēģiju 64 reizes ar 64 sēklām un aplūkojiet rezultātu diapazonu:
Svārstību josla. Viena un tā pati stratēģija, tie paši dati, 64 ar sēklām noteikti vienādu rezultātu atrisināšanas un izpildes secības varianti. Sharpe p5 1.12, mediāna 1.27, p95 1.41. Joslas platums 0.29.
Tagad atgriezieties pie parametru pārbaudes. Labākā konfigurācija ieguva 1.46. Konfigurācija, kas ierindojās 40. vietā no 96, ieguva 1.31. Atšķirība starp tām ir 0.15, kas ir puse no joslas platuma. Pārbaude šīs divas konfigurācijas nesarindoja. Tā paņēma pa vienam paraugam no katras konfigurācijas sadalījuma un sakārtoja šos paraugus.
Šī atziņa mainīja to, kā mēs izvēlamies. Pārbaudes rezultāts ir rangs tikai tad, ja atšķirības starp konfigurācijām pārsniedz vienas konfigurācijas svārstības; stratēģijai, kas atkarīga no izpildes ceļa un ietver 1,400 darījumu, svārstības parasti ir tik lielas, ka līderu saraksta augšējā trešdaļa kļūst par vienādu rezultātu grupu. Tad izvēlieties pēc kritērija, ko svārstību josla nespēj noslēpt: mazāka apgrozība, mazāk parametru, izmaksu pieņēmums, ko spētu aizstāvēt skeptiķa priekšā, vai labāka darbība tajā walk-forward periodā, kas jums patīk vismazāk. Tie ir īsti kritēriji vienādu rezultātu atrisināšanai. 0.15 Sharpe priekšrocība tāda nav.
Vēl viena lieta, ko vērts izdarīt, pirms uzticaties jebkuram no šiem rezultātiem. Palaidiet savu backtestu 2 reizes jau tagad, salīdziniet kapitālu katrā joslā un noskaidrojiet, vai esat bitu līmenī identisko rezultātu grupā vai 0.15 grupā. Tas aizņem 15 minūtes un parāda, cik liela jūsu pētniecības vēstures daļa mērīja stratēģiju un cik liela — jaucējvērtības sēklu.
← Visi raksti

