Het trainen van een model op data die al 'vervuild' is met de toekomst
Je staat te popelen om je algoritmische trading bot te trainen, je hebt een mooie dataset verzameld, je Python-script klaarstaat en je backtest ziet er veelbelovend uit. Maar er sluimert een gevaar dat bijna elke beginner neerhaalt: je traint je model op data die eigenlijk al naar de toekomst kijkt.
Het klinkt gek, maar het gebeurt sneller dan je denkt. Je model leert niet wat je denkt dat het leert, en je bot faalt zodra de echte markt begint.
Wat is ‘vervuild’ met de toekomst eigenlijk?
Stel je voor dat je een voetbalcoach bent die zijn spelers traint met een video waarin het eindscore al in beeld staat. Natuurlijk presteren ze fantastisch in de oefenwedstrijd.
Ze weten immers precies waar de bal gaat landen. In een echte wedstrijd, zonder die voorkennis, lopen ze constant mis.
Precies datzelfde probleem heet ‘lookahead bias’ of data leakage. In trading termen betekent het dat je model tijdens de training toegang heeft tot informatie die op dat moment nog niet beschikbaar was. Denk aan het sluiten van de dagkoers voordat je die gebruikt om een positie te openen, of het berekenen van een indicator op basis van de complete dagdata terwijl je in real-time alleen intraday data hebt.
Je backtest ziet er prachtig uit, maar de live resultaten zijn bedroevend. Het gevaar zit ‘m vaak in details. Misschien gebruik je een API van een broker zoals Interactive Brokers of Degiro, maar je script verwerkt de historische data in de verkeerde volgorde. Of je normaliseert de prijzen over de hele dataset heen, terwijl je in de live markt alleen het verleden kent. Je model traint op een schone, perfecte dataset die in de praktijk niet bestaat.
Waarom dit je bot kan maken of kraken
Een model dat getraind is op vervuilde data voelt zich als een vis in het water tijdens de backtest, maar stikt zodra het live gaat.
Je winstpercentage kan in de backtest 80% zijn, maar in de praktijk zakt het naar 40% of lager. Het verschil tussen een werkende bot en een die constant verliest, zit hem vaak in deze fout. Stel je voor dat je een bot bouwt die handelt op basis van een 50-day moving average crossover. In je backtest bereken je de crossover op basis van de complete dataset, inclusief de data van morgen.
Je bot ‘weet’ dus al dat de crossover gaat gebeuren voordat het in de echte markt gebeurt. Je backtest toont prachtige winsten, maar live handelt je bot te laat of te vroeg.
De financiële impact is direct merkbaar. Een bot die €10.000 start en in de backtest €15.000 zou worden, kan in de praktijk zakken naar €8.000.
Het verschil van €7.000 verdwijnt niet door marktvolatiliteit, maar door een simpele datasetfout. Bij risicomanagement betekent dit dat je stop-losses en positiegroottes gebaseerd zijn op een vertekend beeld, wat leidt tot onverwachte verliezen. Bovendien beïnvloedt het je vertrouwen.
Als je bot in de backtest consistent wint, maar live constant faalt, ga je twijfelen aan je strategie in plaats van aan je data. Je past je parameters aan, voegt complexiteit toe, en raakt steeds verder verwijderd van een simpele, robuuste oplossing.
Hoe je data lekken herkent en oplost
De eerste stap is simpel: controleer je data flow. Zorg dat elke feature die je model gebruikt, berekend wordt op basis van data die op dat moment beschikbaar was.
Gebruik een rolling window of expanding window voor berekeningen, nooit de volledige dataset. In Python kun je hiervoor Pandas rolling functies gebruiken, maar let op dat je het venster correct sluit.
Een veelvoorkomende val is het normaliseren van prijzen over de hele dataset. Je zet alle prijzen tussen 0 en 1, maar in de live markt ken je de toekomstige min en max niet. Los dit op door per dag te normaliseren op basis van de data tot dat moment. Gebruik een function die voor elke timestamp de normalisatie berekent op basis van het verleden, niet de toekomst.
Backtesting frameworks zoals Backtrader of Zipline helpen hierbij, maar ze zijn niet waterdicht.
Test je code met een simpele sanity check: draai een backtest met een willekeurige dataset en controleer of de resultaten realistisch zijn. Gebruik een broker API zoals die van Interactive Brokers om historische data op te halen en vergelijk deze met je dataset. Verschillen duiden op data leakage.
Een andere praktische tip: split je dataset op tijd, niet willekeurig. Gebruik de eerste 70% voor training, de volgende 20% voor validatie en de laatste 10% voor test.
Nooit de volgorde door elkaar halen. Dit voorkomt dat je model leert van data die later in de tijd plaatsvindt.
Test je model op een out-of-sample periode die je nooit hebt gezien tijdens de ontwikkeling. Bijvoorbeeld: train op data van 2018-2022, test op 2023. Als je resultaten sterk verslechteren, is er sprake van leakage of overfitting. Gebruik een eenvoudige benchmark, zoals een buy-and-hold strategie, om je resultaten te relativeren.
Praktische aanpak voor algoritmische traders
Begin met een simpele Python-setup. Gebruik Pandas voor data verwerking, NumPy voor berekeningen en een backtesting library zoals Backtrader of een lichtgewicht alternatief zoals vectorbt.
Installeer deze via pip en zorg dat je een virtuele omgeving gebruikt om dependencies te isoleren. Kosten: nul, tenzij je premium data koopt (bijvoorbeeld €50-€200 per maand voor kwaliteitsdata). Stap 1: Haal je data op via een broker API of een dienst als Alpha Vantage of Quandl.
Zorg dat de tijdstempels correct zijn en dat je geen gaten in de data hebt.
Voor een bot die op de AEX handelt, gebruik je bijvoorbeeld intraday data van 1 minuut, maar test eerst op dagdata om complexiteit te vermijden. Stap 2: Bereken je features met een rolling window. Voor een 20-day RSI: gebruik alleen data tot en met de huidige dag. Schrijf een functie die voor elke dag de RSI berekent op basis van de voorgaande 20 dagen.
Test deze functie op een kleine dataset om te controleren of er geen toekomstige data in glipt. Stap 3: Train je model met een time-series split.
Gebruik Scikit-learn’s TimeSeriesSplit of schrijf een simpele loop die steeds een stap verder gaat in de tijd. Voor een eenvoudig lineair model: voer je features in en train op de eerste 70% van de data. Evalueer op de volgende 20% en tune je parameters voorzichtig.
Stap 4: Backtest je bot met realistische kosten. Neem transactiekosten van €2-€5 per trade en slippage van 0,1% mee.
Gebruik een broker zoals Interactive Brokers voor realistische executie. Als je bot in de backtest €1.000 wint maar €500 aan kosten heeft, is het rendement al gehalveerd. Stap 5: Monitor live met een paper trading account.
Test je bot eerst met nepgeld via de API van je broker. Kijk of de resultaten overeenkomen met je backtest.
Als niet, controleer dan opnieuw op data leakage. Pas je risicomanagement aan: zet een max drawdown limiet van 10-15% en position sizing van max 2% per trade.
Varianten en modellen met prijsindicaties
Er zijn verschillende benaderingen om data leakage te vermijden, afhankelijk van je modelcomplexiteit.
Voor een eenvoudige trend-following bot: gebruik een dual moving average crossover. Train een lineair regressiemodel op features zoals RSI, MACD en volume, en vergeet niet om je getrainde model correct op te slaan voor live trading.
Kosten: nul voor de code, €50-€100 per maand voor data. Voor een meer geavanceerde aanpak: gebruik een LSTM-neuraal netwerk via TensorFlow of PyTorch. Omdat je bij deze modellen moet weten hoeveel data je minimaal nodig hebt, is een strakke time-series split essentieel om leakage te voorkomen. Train op een GPU instance (bijvoorbeeld via Google Colab, gratis of €10-€20 per maand voor premium).
Backtest met dezelfde library, maar voeg noise toe aan je data om overfitting te testen.
Een andere variant: ensemble modellen, zoals een random forest op basis van meerdere indicatoren. Gebruik Scikit-learn en zorg dat elke feature tijdens training alleen verleden data gebruikt. Prijsindicatie: een eenvoudige random forest bot bouwen kost je tijd, maar geen geld.
Een professionele setup met data feeds en een dedicated server loopt op tot €100-€300 per maand. Vergeet niet risicomanagement te integreren.
Gebruik een Kelly criterion voor position sizing of een eenvoudige fixed fractional methode.
Test dit in je backtest door drawdowns te simuleren. Als je bot een maximale drawdown van 20% heeft, verlaag dan je positiegrootte tot 1% per trade. Dit verlaagt je winstpotentieel maar beschermt je kapitaal.
Als je serieus bent over algoritmisch traden, investeer in een betrouwbare broker API en een backtesting omgeving die leakage detecteert. Een setup met Interactive Brokers, Python en een cloud server kost je €50-€150 per maand, maar bespaart je duizenden euro’s aan fouten.
Praktische tips om direct toe te passen
- Check altijd je data flow: schrijf een simpele debug-functie die laat zien welke data gebruikt wordt per timestamp.
- Gebruik time-series splits, nooit random splits. Zorg dat je validatie en test set in de toekomst liggen ten opzichte van je training set.
- Test op een out-of-sample periode van minstens 6 maanden. Als je bot daar flopt, is er leakage of overfitting.
- Integreer realistische kosten: transactiekosten, slippage en spread. Gebruik een broker zoals Degiro voor lage kosten (€2-€3 per trade) of Interactive Brokers voor wereldwijde markten.
- Monitor continu: draai je backtest maandelijks op nieuwe data. Als de prestaties verslechteren, onderzoek dan opnieuw op leakage.
- Houd het simpel: begin met een bot die op dagdata handelt, voeg complexiteit toe als je basis stabiel is. Een eenvoudige bot die €500 per maand wint is beter dan een complexe die €2.000 verliest.
- Documenteer elke stap: schrijf op hoe je features berekent, welke data je gebruikt en welke aannames je maakt. Dit helpt bij het opsporen van fouten.
Onthoud: een bot die getraind is op schone, toekomst-vrije data is robuuster en voorspelbaarder. Neem de tijd om te checken of jouw dataset klaar is voor machine learning, je code te testen en je resultaten te valideren. Je zult merken dat je live prestaties verbeteren, en je vertrouwen in je algoritmische strategie groeit. Succes!
