Wat is 'Combinatorial Purged Cross-Validation' (CPCV)?
Stel je voor: je hebt een prachtige trading strategie gebouwd in Python.
Je backtesten in MetaTrader 5 of via de Interactive Brokers API laten fantastische resultaten zien. Je eigen bot draait en de winst stroomt binnen.
Tot je hem live zet en... boem. De markt verandert een beetje, en je bot gaat als een speer naar beneden. Wat is er misgegaan? Het antwoord ligt vaak verborgen in je testmethode.
Je hebt je strategie getest op data die hij al kende. Dat is als een student die de antwoorden van de toets krijgt voordat hij hem maakt; het zegt niets over zijn echte kennis.
Om je bot écht te testen, heb je een ijzersterke, realistische testmethode nodig. Een die data lekt, net als in het echt. En daar komt CPCV om de hoek kijken.
Wat is Combinatorial Purged Cross-Validation?
Combinatorial Purged Cross-Validation, of kortweg CPCV, is een geavanceerde testmethode voor algoritmische trading bots. Stel je voor dat je een enorme dataset hebt, bijvoorbeeld 5 jaar aan EUR/USD prijsdata. Je wilt je strategie testen, maar je wilt niet dat de bot in de toekomst kijkt.
Bij traditionele methoden splits je de data op in een trainingsdeel en een testdeel.
Maar wat als het beste moment om te kopen precies op de scheiding valt? Dan lekt er informatie door.
CPCV lost dit op door op een slimme, wiskundige manier alle mogelijke combinaties van trainings- en testdata te bekijken. Het is alsof je een gigantische puzzel legt waarbij elk stukje data zowel in de hoek (training) als in het midden (test) heeft gelegen, maar nooit tegelijk. Het 'Purged' gedeelte is hier de echte game-changer.
In de echte markt kun je niet zomaar een trade openen en direct daarna de resultaten weten.
Er zit tijd tussen, de 'hold' periode. CPCV begrijpt dit. Het verwijdert (purged) data die te dicht bij de testperiode ligt. Stel je trade een 'lookahead bias' van 10 candles hebt. Dan zorgt CPCV ervoor dat de data direct vóór de testperiode niet in de trainingsset komt.
Zo voorkomt het dat je bot indirect 'weet' wat er net is gebeurd. Het resultaat? Een veel realistischer beeld van hoe je bot het in de echte wereld zou doen. Geen vals optimisme, maar harde, eerlijke cijfers.
Waarom is dit cruciaal voor jouw trading bot?
Veel traders die met Python en API's van brokers zoals Interactive Brokers of LMAX werken, maken dezelfde fout.
Ze finetunen hun parameters op een specifieke periode. Ze draaien een backtest over 2021, passen de parameters aan, draaien hem opnieuw, enzovoort.
Uiteindelijk krijgen ze een set parameters die perfect werkt voor 2021. Maar in 2022 of 2023 falen ze jammerlijk. Dit is 'overfitting' of 'curve-fitting'. Je past je model te strak aan op de ruis van het verleden.
CPCV is de ultieme remedie tegen overfitting. Omdat het de data in zoveel verschillende configuraties test, dwingt het je bot om te presteren onder diverse marktomstandigheden.
Het is de ultieme stresstest voor je code. Een ander groot gevaar is 'lookahead bias'. Dit is een subtiele maar dodelijke fout in je backtesting code.
Bijvoorbeeld: je sluit een trade op basis van de slotkoers van de dag, maar je backtest rekent de winst alsof je die koers al om 12:00 uur had. CPCV, en dan met name de 'purged' variant, maakt dit onmogelijk.
Door de data strategisch te verwijderen rondom de testmomenten, zorgt het ervoor dat je model nooit toegang heeft tot data die het in het echt niet had.
Dit geeft je de garantie dat je backtestresultaten enigszins betrouwbaar zijn door middel van kruisvalidatie voor trading strategieën. Het bespaart je duizenden euro's aan verkeerd geïnvesteerd kapitaal in een bot die eigenlijk al gebreken had.
Hoe werkt CPCV in de praktijk?
De kern van CPCV is het combineren van data splitsingen. Laten we het simpel houden.
Stel je hebt een dataset van 10 dagen. Een simpele splitsing is: dagen 1-7 voor training, 8-10 voor test. Een volgende split is: 1-4 en 6-8 voor training, 9-10 voor test.
CPCV maakt veel van deze splitsingen. Het algoritme zorgt ervoor dat elke mogelijke combinatie van data aan bod komt, met de restrictie dat trainings- en testdata nooit overlappen.
Het 'Purged' gedeelte zorgt dat er een buffer is. Als je een trade aanhoudt voor 3 dagen, worden de 3 dagen voorafgaand aan een testperiode verwijderd uit de trainingsdata. Dit voorkomt dat je model traint op data die direct relevant is voor de test. Stel je voor dat je een bot bouwt die handelt op basis van een RSI-crossover op de 1-uur grafiek van de DAX.
Je hebt 2 jaar aan data. Je wilt weten of je parameters (bijv.
RSI periode 14 vs 21) robuust zijn. Je gebruikt CPCV. Het algoritme zal je data opdelen in bijvoorbeeld 10 of 20 folds. Elke fold is een testset.
De rest is training. Maar door de purging weet je zeker dat je resultaten niet vertekend zijn door de 'lookahead' van je trade.
De uitkomst is een distributie van prestaties (bijv. Sharpe ratio, winstpercentage) over al die folds. Je ziet niet één getal, maar een range.
Als de range breed is, is je strategie onbetrouwbaar. Als hij smal is en consistent positief, heb je goud in handen.
Modellen, implementatie en kosten
Er bestaat geen kant-en-klaar 'CPCV-product' dat je even koopt. Het is een concept dat je implementeert in je eigen Python omgeving.
De meeste traders bouwen dit zelf of gebruiken bibliotheken die dit soort functionaliteit bieden. De populairste bibliotheek hiervoor is mlfinlab.
Deze library, ontwikkeld door het universiteit van Miami, bevat een kant-en-klare implementatie van Purged Combinatorial Cross-Validation. De library is gratis en open-source. Je kunt hem simpelweg installeren via `pip install mlfinlab` in je Python omgeving. De enige 'kosten' zijn je eigen tijd om de library te integreren in je backtesting framework.
De implementatie vraagt wel wat kennis. Je moet je data in het juiste format aanleveren (meestal een Pandas DataFrame met een index en prijskolommen) en je labels definiëren (wanneer een trade start en eindigt).
De functie `get_train_val_splits` uit mlfinlab doet dan het zware werk. Als je dit te ingewikkeld vindt, zijn er alternatieven. Je kunt een simpelere Time Series Cross-Validation toepassen, maar dan loop je dus het risico van lookahead bias.
Er zijn ook betaalde backtesting frameworks voor Python, zoals Backtrader of Zipline, maar de meeste geven je niet standaard CPCV. Je zult vaak alsnog je eigen implementatie moeten schrijven of een externe library gebruiken. De investering in tijd om CPCV te leren is vele malen lager dan het verlies dat je kunt lijden door een slecht geteste bot.
Praktische tips voor CPCV in jouw trading
Begin klein. Je hoeft niet meteen je complete, complexe bot met 50 parameters te testen.
Pak een simpele strategie, bijvoorbeeld een moving average crossover op Bitcoin. Pak 2 jaar aan data van een broker als Bybit of Binance. Schrijf een simpel scriptje in Python met behulp van mlfinlab om CPCV toe te passen. Bekijk de resultaten.
Zie je een breed verschil in resultaten tussen de folds? Dan is je strategie waarschijnlijk te afhankelijk van specifieke marktperiodes. Voorkom over-optimization in volatiele markten. Zie je consistentie?
Dan ben je op de goede weg. Dit oefenen met een eenvoudig model geeft je het gevoel voor de kracht van de methode. Pas de purging-periode zorgvuldig toe.
De grootte van de 'purge' hangt af van je handelsstijl. Een high-frequency bot die trades binnen minuten sluit, heeft een veel kleinere purge nodig (bijvoorbeeld 10 minuten) dan een bot die posities wekenlang vasthoudt.
Als je posities 5 dagen aanhoudt, moet je er bijvoorbeeld voor zorgen dat de 5 dagen vóór je testperiode uit de trainingsset worden gehaald.
Een veelgemaakte fout is een te kleine purge, wat alsnog tot lookahead bias leidt. Een te grote purge is minder erg, maar je verspilt kostbare data. Test dus met verschillende purge-instellingen om te zien hoe gevoelig je model daarop is. Gebruik CPCV niet alleen voor het testen van je strategie, maar ook voor het optimaliseren van je parameters.
In plaats van alle parameters te tunen op één specifieke dataset, deel je je data op met CPCV. Je traint op de trainingsfolds en valideert op de validatiefolds.
De parameters die over de meeste folds heen de beste prestaties geven, zijn de meest robuuste. Zo bouw je een bot die niet alleen in het verleden werkt, maar die klaar is voor de toekomst. Onthoud altijd: een bot die goed presteert onder CPCV is een bot met potentie. Het is de ultieme kwaliteitscheck voor je algoritme.
