Hoe ga je om met 'Over-optimization' in een volatiele markt?
Je kent het wel: je hebt een strategie gebouwd die in de backtest op Python perfect loopt.
Je broker API knippert vrolijk, de winstcurve gaat omhoog en je bent er bijna. Tot je live gaat en de markt plotseling volatiel wordt. De bot faalt. Wat is er misgegaan? Over-optimization.
Je hebt je model te strak gesneden naar historische data, waardoor het in de echte wereld niet meer werkt. Dit stappenplan helpt je om die val te vermijden en een robuuste bot te bouwen die wel tegen een stootje kan.
Stap 1: Zet je gereedschap klaar
Voordat je begint, zorg je dat je een stabiele omgeving hebt. Gebruik Python 3.11 of nieuwer, en een virtuele omgeving.
Installeer de libraries die je echt nodig hebt: backtesting.py of Zipline voor backtests, pandas voor data, ccxt of de officiële API van je broker voor order routing, en pyfolio of empyrical voor performance-analyse. Voor risicomanagement kijk je naar libraries als quantstats. Zorg dat je API-sleutels van je broker (bijvoorbeeld Interactive Brokers, Kraken of Binance) veilig staan, bijvoorbeeld via environment variables.
- Python 3.11+ en een virtuele omgeving
- Backtesting.py of Zipline (lokaal)
- ccxt of broker-specifieke Python SDK
- pandas, numpy, pyfolio, quantstats
- API-sleutels in .env of secrets manager
Reken op een uur voorinstallatie en configuratie. Veelgemaakte fout: direct live keys gebruiken in testcode.
Gebruik altijd een testaccount en sandbox-omgevingen van je broker.
Stap 2: Verzamel en prepareer data zonder te snoeien
Over-optimization begint bij data. Haal brede, schone datasets op.
Gebruik minimaal 5 tot 10 jaar historische data voor je assets, inclusief intraday als je dat doet.
- Download 5-10 jaar OHLCV data per asset (minimaal 1.000 handelsdagen)
- Check op gaps, splitsingen en dividends; corrigeer met adjusted close
- Voeg macro- en sector-indicatoren toe (VIX, rentes, sector-ETFs)
- Splits data in in-sample (70%) en out-of-sample (30%)
- Log alles: data bron, frequentie, tijdzone, bewerkingen
Voor een aandelenbot met Interactive Brokers haal je via de API of een dienst als Alpaca/IBKR data op vanaf 2014 tot nu. Voor crypto via Binance of Kraken pak je minimaal 5 jaar tick- of 1-minuutdata. Sla ook marktregimes op: bull, bear, zijwaarts, en events zoals de coronacrash of de oorlog in Oekraïne.
Reken op 2-4 uur voor data verzameling en cleaning. Veelgemaakte fout: data snoeien tot alleen de mooie periodes. Laat de moeilijke marktregimes erin; die zijn je beste test.
Stap 3: Definieer je parameters met gezond verstand
Zet je parameters op papier voordat je codeert. Kies een beperkt aantal variabelen die je echt wilt tunen.
Voor een moving-average crossover-bot bijvoorbeeld: short_window (5-20), long_window (50-200), stop-loss (1-5%), position sizing (1-3% van equity per trade), en max open posities (1-5). Koppel elk parameterbereik aan een logische reden. Een short_window van 3 werkt in backtests, maar is waarschijnlijk te snel voor de realiteit.
- Short window: 5-20 candles
- Long window: 50-200 candles
- Stop-loss: 1-5% (afhankelijk van asset volatiliteit)
- Position sizing: 1-3% van equity
- Max posities: 1-5
Gebruik een parameter logboek. Noteer per parameter: minimale waarde, maximale waarde, stapgrootte, en rationale.
Veelgemaakte fout: te veel parameters tegelijk tunen. Beperk je tot 3-5 kernparameters, en houd daarbij rekening met de invloed van transaction costs op je optimale parameters.
Stap 4: Backtest met robuustheid in het hoofd
Backtesten is meer dan winstcurve plotten. Test onder meerdere marktregimes en met realistische kosten.
Simuleer broker fees (bijvoorbeeld €0,01 per aandeel of 0,1% bij crypto) en slippage (0,05-0,2% voor aandelen, 0,1-0,5% voor crypto).
- Run een first-pass backtest met ruwe parameters
- Voeg fees en slippage toe (zie boven)
- Voer walk-forward uit: tune in-sample, test out-of-sample
- Draai minimaal 3 marktregimes: bull, bear, zijwaarts
- Bewaar elke run: datum, parameters, equity curve, drawdown
Gebruik walk-forward optimalisatie: tune parameters op in-sample data en valideer op out-of-sample. Herhaal dit in meerdere ramen om te zien of de strategie stabiel blijft. Reken op 4-8 uur voor een grondige backtestreeks.
Veelgemaakte fout: alleen de beste run rapporteren. Rapporteer de mediaan en het 25e/75e percentiel van alle runs.
Stap 5: Valideer met out-of-sample en forward test
Out-of-sample is je echte proef. Gebruik een aparte dataset die je model nooit heeft gezien.
Voor aandelen kun je de afgelopen 12-18 maanden als forward test gebruiken; voor crypto de laatste 6-12 maanden vanwege hogere volatiliteit.
- Out-of-sample: minimaal 12 maanden aandelen, 6 maanden crypto
- Paper trading bij je broker (IBKR, Binance Testnet, Kraken demo)
- Log elke API-call en broker response
- Vergelijk live fills met backtest assumpties
- Check slippage en fees in de praktijk
Zet de bot aan in een paper trading omgeving bij je broker. Monitor de orderuitvoering: wachttijden, fill rates, cancellaties. Als je via API handelt, log elke order en response van je broker.
Reken op 1-2 weken voor een degelijke forward test. Veelgemaakte fout: te snel live gaan na een goede out-of-sample. Wacht tot je minimaal 30-50 trades hebt gezien in paper trading.
Stap 6: Risicomanagement en position sizing inbouwen
Over-optimization verdwijnt niet zonder risicobescherming. Zet harde limieten op je portefeuille.
Gebruik een max dagelijks verlies (bijvoorbeeld 2-3%) en een max drawdown limiet (bijvoorbeeld 10-15%). Pas position sizing toe met Kelly of een eenvoudige fixed-fractional methode. Voor een account van €10.000 betekent 2% risico per trade maximaal €200 verlies per trade.
- Stel max dagelijks verlies in (2-3% van equity)
- Stel max drawdown limiet in (10-15%)
- Kies position sizing: fixed fractional (1-2%) of Kelly conservatief
- Voeg circuit breakers toe: stop na X verliezen op rij
- Log elke risico-actie in een audit trail
Stop de bot automatisch als de limiet wordt geraakt. Reken op 2-3 uur voor risico-inrichting.
Veelgemaakte fout: geen automatische stop. Handmatig ingrijpen werkt niet in volatiele markten; zet het in de code.
Stap 7: Monitor, log en onderhoud
Een bot is een levend systeem. Monitor elke dag: winst, drawdown, aantal trades, slippage, en API-uptime. Gebruik dashboards (bijvoorbeeld Grafana) en stuur alerts naar Telegram of Slack.
Plan wekelijks een onderhoudssessie: check of parameters nog kloppen, of de marktstructuur is veranderd, en of je data pipelines nog lopen.
- Dagelijkse monitoring: equity, drawdown, trades, slippage
- Alerts via Telegram/Slack bij fouten of grote bewegingen
- Wekelijks onderhoud: parameter sanity check
- Maandelijkse review: marktregimes, performance vs backtest
- Log alle wijzigingen in een versiebeheer (Git)
Voor Python bots is een eenvoudige cron-job of Airflow DAG voldoende. Reken op 1 uur per week voor monitoring en 2 uur per maand voor onderhoud.
Veelgemaakte fout: niet loggen wat je wijzigt. Zonder log is herstel bij problemen lastig.
Verificatie-checklist
- Gebruik je minimaal 5-10 jaar data met meerdere marktregimes?
- Heb je in-sample en out-of-sample duidelijk gescheiden?
- Zijn fees en slippage realistisch ingevuld?
- Beperk je het aantal parameters tot 3-5 met logische ranges?
- Voer je walk-forward analyse uit en rapporteer mediaan-percentielen?
- Test je minimaal 12 maanden aandelen of 6 maanden crypto forward?
- Gebruik je paper trading bij je broker en log je API-responses?
- Staan er harde risicolimieten en automatische stops in de code?
- Monitor je dagelijks en onderhoud je wekelijks/maandelijks?
- Documenteer je elke wijziging en hou een audit trail bij?
Als je deze checklist afrondt, heb je een bot die niet alleen in de backtest schittert, maar ook in een volatiele markt zijn werk doet. Herken de 5 tekenen van over-optimalisatie, zodat dit geen valkuil meer is, maar een les die je hebt verwerkt.
