Hoe je een trading strategie optimaliseert zonder te 'overfitten'
Je kent het wel: je hebt een strategie gebouwd die in de backtest glorieus presteert. Je equity curve stijgt als een raket, de drawdown is minimaal en je bent er klaar voor om de markt te veroveren.
Tot je hem live zet en de boel keihard instort. Dit is de klassieke valkuil van overfitting, oftewel: je model past zo perfect op historische data dat het toeval als signaal gaat zien.
We gaan samen een strategie optimaliseren die wél werkt, zonder te overdrijven. Stel je voor: we bouwen een bot in Python, testen hem bij Interactive Brokers of een andere broker, en zorgen dat ie in de echte wereld niet als een zeepbel uiteenspat. Je hebt geen magische bol nodig, maar wel een plan. Hier is een concrete, praktische handleiding zonder fluff, met getallen die je kunt voelen.
Wat je nodig hebt voordat je begint
Zorg dat je een stabiele Python-omgeving draait (minimaal 3.10), met packages als pandas, numpy, backtrader of vectorbt, en eventueel ccxt voor crypto. Reken op 8–16 GB RAM voor grotere datasets; een SSD is een must.
Voor data kun je kijken naar providers als Alpaca, Yahoo Finance (via yfinance), of een betaalde broker-API met tickdata.
Voor live trading heb je een broker-API nodig, bijvoorbeeld Interactive Brokers (TWS API), of een crypto-exchange via ccxt. Voor risicomanagement is een VPS met lage latency handig, bijvoorbeeld een instance van €5–15 per maand. Je hebt verder een backtesting-framework nodig.
Vectorbt is snel voor vectorized tests, Backtrader is flexibeler voor orderlogica. Zorg dat je een aparte Python-omgeving per strategie gebruikt, bijvoorbeeld via conda.
Voor dataopslag kies je voor parquet-bestanden, die zijn compact en snel. En tot slot: een eenvoudig logboek (CSV of SQLite) om elke trade en beslissing vast te leggen.
Stap 1: definieer een simpele, logische basisstrategie
Begin met een heldere, eenvoudige regelset. Voorbeeld: een trendvolgende strategie op SPY of een crypto-paar zoals BTC/USDT, met een 20-dagen moving average en een ATR-gestuurde stop.
- Kies een markt en timeframe: SPY op dag, of BTC/USDT op 1 uur. Hou rekening met handelskosten van 0,01–0,05% per trade bij crypto, en €2–5 per order bij traditionele brokers.
- Definieer indicators: 20-perioden SMA voor trend, ATR(14) voor stop. Voeg geen extra indicators toe zonder reden.
- Regels vastleggen: long als price > SMA, short als price < SMA. Stop op ATR-multiples (bijv. 1,5 × ATR), take-profit optioneel (bijv. 3 × ATR).
- Logica in code: schrijf een function die elke candle verwerkt, met duidelijke entry/exit-voorwaarden. Test of de code compenseert voor fees en slippage.
Gebruik een entry- en exit-criterium dat je kunt uitleggen aan een vriend. Vermijd complexe, opgeplakte filters in deze fase. Veelgemaakte fout: te veel parameters vanaf het begin.
Houd het bij maximaal 3–4 kernparameters. Zodra je basis staat, kun je kijken naar parameter optimization. Tijdsindicatie: 1–2 uur voor de basiscode.
Hou het simpel. Een strategie die je in één zin kunt uitleggen, is makkelijker te debuggen.
Stap 2: verzamel en prepareer je data
Goede data is de basis voor betrouwbare backtests. Gebruik OHLCV-data van minimaal 3–5 jaar voor dagdata, of 1–2 jaar voor intraday.
- Download data: voor SPY via Yahoo (yfinance), voor crypto via ccxt of een provider als Binance. Sla op in parquet: per maand of per jaar.
- Clean data: verwijder nullen, pas splitsingen/adjustments toe bij aandelen. Controleer op outliers (bijv. price spikes van 10×).
- Voeg costs toe: reken met 0,1% roundtrip bij crypto, €5 per order bij traditionele brokers. Slippage: 0,05–0,10% voor liquiditeitsmarkten.
- Split data: train (eerste 70%), validatie (20%), out-of-sample (10%). Gebruik time-based splits, geen shuffle.
Voor crypto: let op stablecoin-paren en vermijd data met hiaten of forks. Veelgemaakte fout: lookahead bias door future data te gebruiken (bijv. ongecorrigeerde sluitingsprijzen voor indicators). Tijdsindicatie: 2–4 uur voor data-verwerking.
Stap 3: backtest met costs, slippage en realistische executie
Een backtest zonder kosten is een sprookje. Zorg dat je broker-specifieke limieten en executie-regels simuleert. Bij IBKR kun je de TWS API gebruiken voor orderlogica; bij crypto kijk je naar orderbook-simulaties.
- Framework kiezen: vectorbt voor snelle tests, Backtrader voor ordernauwkeurigheid. Voor eenvoudige scripts: je eigen loop met pandas.
- Costs inbouwen: 0,1% roundtrip crypto, €2–5 per aandelenorder. Slippage: 0,05–0,10% afhankelijk van liquiditeit.
- Executie regels: limietorders vs marketorders. Test met een spread van 0,01–0,05% voor populaire crypto-paren.
- Performance metrics: CAGR, Sharpe ratio, max drawdown, winstpercentage, gemiddelde winst/verlies. Let op: Sharpe > 1 is oké, > 1,5 is goed, > 2 is zeldzaam.
Veelgemaakte fout: te optimistische aannames over fills. Test met een worst-case slippage van 0,2% om te zien of de strategie overleeft.
Tijdsindicatie: 2–3 uur voor een eerste volledige backtest.
Stap 4: optimaliseer zonder te overfitten
Optimalisatie is geen doel op zich; het is een manier om robuustheid te testen. Gebruik een kleine, logische parameter-ruimte en bewaar een out-of-sample set voor de eindcontrole. Veelgemaakte fout: optimaliseren op de hele dataset en dan direct live gaan. Vraag je je af hoe vaak je jouw parameters opnieuw moet optimaliseren?
- Beperk parameters: kies 2–4 kernparameters (bijv. SMA-lengte 10–40, ATR-multiple 1,0–2,5). Geen eindeloze grid searches.
- Gebruik walk-forward: verdeel data in 6–12 vensters, optimaliseer per venster en test op het volgende. Dit simuleert live hertrainen.
- Voeg noise toe: test met kleine variaties in startdatum, costs en slippage. Kijk of de prestatie stabiel blijft.
- Regularisatie: kies de eenvoudigste parameter die voldoet (Occam’s razor). Vermijd complexe curves die pieken op één venster.
Altijd een out-of-sample test doen. Tijdsindicatie: 3–6 uur voor walk-forward, afhankelijk van data-omvang.
Een strategie die op 3 verschillende periodes werkt, is sterker dan eentje die op één perfecte curve presteert.
Stap 5: risicomanagement en position sizing
Risicomanagement is het hart van een duurzame bot. Gebruik vaste risico-per-trade en dynamische stops.
- Risico per trade: max 1–2% van je account. Bij een account van €10.000 is dat €100–200 risico per trade.
- Position sizing: bereken aantal eenheden op basis van stop. Voorbeeld: entry €100, stop op €98,50 (1,5% risk), risico €100 → positie van €6.667 (100/0,015).
- Stops en exits: ATR-gestuurde stops (1,5–2,0 × ATR), of percentage-stops. Test trailing stops op verschillende timeframes.
- Exposure: max 10–20% van account per markt. Voor meerdere markten: correlatie-check om te voorkomen dat je in feite één exposure neemt.
- Paper trading: draai 2–4 weken live met kleine sizes (bijv. 0,1 lot of €100 per trade). Check of fills matchen met backtest.
- Monitoring: dashboard met equity curve, drawdown, winst/verlies per trade. Gebruik een tool als Grafana of een simpel Streamlit-dashboard.
- Alerts: stel meldingen in voor crashes, API-errors, of als drawdown > 10% gaat. Check dagelijks de logs.
- Rollout: verhoog stapsgewijs naar 0,5–1% risico per trade. Stop bij een drawdown > 15% en evalueer.
- Strategie is in één zin uit te leggen en heeft max 4 kernparameters.
- Data is geclean, tijdgebaseerd gesplitst, en bevat minimaal 3 jaar voor dagdata.
- Backtest bevat costs (0,1% roundtrip crypto, €2–5 per order) en slippage (0,05–0,2%).
- Walk-forward test laat stabiele prestatie zien op minimaal 6 vensters.
- Out-of-sample prestatie is binnen 20% van de trainingsperiode (geen gat).
- Risico per trade is 1–2%, position sizing is correct berekend op stop.
- Max drawdown in backtest < 20% en Sharpe ratio > 1,0 (liefst > 1,5).
- Live paper trading (2–4 weken) laat vergelijkbare fills en prestatie zien.
- Monitoring is ingericht: dashboard, alerts, logboek en kill-switch.
- Plan voor hertrainen: maandelijks of per venster, met duidelijke criteria.
Zorg dat je geen concentratierisico opbouwt. Veelgemaakte fout: stops te strak zetten waardoor je te snel uitgestopt wordt. Test met 1,5–2,0 × ATR voor meer ademruimte. Tijdsindicatie: 1–2 uur voor risico-scenario’s.
Stap 6: live-test en monitoring
Start klein en meet alles. Gebruik een VPS dicht bij je broker voor lage latency, en log elke actie.
Veelgemaakte fout: te snel opschalen na een paar goede trades. Houd een plan B klaar: een kill-switch voor de bot. Voorkom teleurstelling in de live markt door een degelijke live-test van 2–4 weken.
Verificatie-checklist
Gebruik deze checklist voordat je echt geld inzet. Vink elk punt af en noteer je bevindingen.
Als je deze stappen volgt, bouw je een trading bot die niet alleen mooi op papier staat, maar in de echte markt overeind blijft.
En onthoud: robuustheid is belangrijker dan perfectie. Begin klein, meet veel, en groei stapsgewijs.
