Walk-forward-optimering har ry for at være den ærlige måde at tune en strategi på, og det ry er fortjent — sammenlignet med at optimere på alle data og beundre resultatet. Men teknikken har stille fejlformer, og hver af dem producerer den samme artefakt: en valideringsrapport, der siger "robust", hæftet på en strategi, der ikke er det. Her er de tre, vi har måttet konstruere os ud af, sorteret efter det vrag, de efterlader.
Fejl ét: vinduerne lækker
Den forkerte måde: tun på januar-juni, valider på juli, og lad så noget fra juli påvirke en anden runde — et gen-kør efter at have set out-of-sample-tallet, en "lille justering" af parametergitteret, en feature normaliseret over hele serien. Hver enkelt ser uskyldig ud. Tilsammen forvandler de out-of-sample-vinduet til in-sample-data med forsinkelse.
Vraget: en out-of-sample-Sharpe, der på mystisk vis følger in-sample-Sharpe. Ægte out-of-sample-resultater er støjende og skuffende; en mistænkeligt glat IS/OOS-sammenhæng betyder, at information flyder baglæns. Vi holder eksplicit øje med forholdet — in-sample mere end 3x out-of-sample flager kørslen, og out-of-sample på eller under nul dræber den, uanset hvor pænt in-sample ser ud.
Fejl to: metrik-shopping på tværs af vinduer
Kør tre walk-forward-vinduer, få tre støjende resultater, og opsummer så: gennemsnitlig Sharpe? Median? Smide det værste vindue ud på grund af "regimeskifte"? Hvert valg er en frihedsgrad, og en vedholdende optimerer (menneskelig eller bayesiansk) finder den opsummering, hvorunder netop denne strategi ser bedst ud. Femoghalvfjerds Optuna-forsøg pr. vindue er femoghalvfjerds chancer for at tilpasse støj, ganget med hvor mange opsummeringer du er villig til at overveje.
Vraget: en strategi, der består valideringen og derefter leverer det værste vindues performance live, fordi det værste vindue var det eneste ærlige. Vores regel: aggregeringen fastlægges i config før kørslen, forsøgsbudgettet er fastlagt, og analytikeren læser resultater pr. vindue med spredningen synlig. En strategi, der har brug for den venlige opsummering for at bestå, består ikke.
Fejl tre: det holdout, der holdt op med at være et
Et holdout virker præcis én gang. Anden gang en strategi bliver evalueret mod det — efter et parameterpuf, en signaljustering, et "lad os lige tjekke" — er det ikke et holdout længere; det er et langsomt valideringssæt. Femten urørte dage lyder trivielt at bevare, indtil iterationspresset melder sig, og et gentjek føles harmløst.
Vraget er subtilt: holdout-resultater, der bliver bedre hen over iterationer af den samme strategi. Friske out-of-sample-data har ingen grund til at belønne iteration tre frem for iteration ét, og når de gør det, er holdoutet blevet minet. Vi håndhæver ét-skuds-reglen mekanisk: holdoutet evaluerer én gang pr. pipeline-kørsel, resultatet skrives til journalen, og en strategi, der har brug for endnu et forsøg, skal hele vejen gennem spidsrodsløbet igen — nye vinduer og det hele. Den skal bevare mindst 70% af walk-forward-out-of-sample-Sharpe, og der er ikke noget andet kast med den terning.
Det kendetegn, der overlever alle tre
Før noget af det kører vi et almindeligt følsomhedssweep: puf hver parameter ±20% og hold øje med metrikkerne. En ægte edge degraderer yndefuldt; et tilfælde falder ud over en klippekant. Det er den billigste test i pipelinen, og den nedlægger veto mod strategier, der ellers ville have sejlet igennem alt ovenstående — for en parameterklippe er, hvordan overfitting ser ud, før du har givet den en chance for at gemme sig i valideringsmaskineriet.
Intet af dette gør optimering sikker. Det gør fejlformerne larmende — og det er det mest, man ærligt kan forlange af en valideringsproces.
← Alle indlæg