De architectuur van Backtrader: Hoe bouw je een herbruikbare strategie?
Stel je voor: je hebt een strategie in je hoofd die eigenlijk best logisch klinkt. Je wilt ‘m testen op historische data, zonder meteen je zuurverdiende euro’s op het spel te zetten.
Backtrader is daarvoor je beste vriend. Het is een open-source Python-bibliotheek die je helpt bij het bouwen, testen en optimaliseren van handelsstrategieën.
In dit stuk ga je stap voor stap leren hoe je een strategie bouwt die je keer op keer kunt hergebruiken, zonder dat je elke keer opnieuw het wiel uitvindt. We gaan voor een aanpak die je morgen nog kunt toepassen.
Wat je nodig hebt voordat je begint
Voordat je code typt, zorg je dat je omgeving stabiel is. Je hebt Python 3.8 of nieuwer nodig.
Gebruik een virtuele omgeving, bijvoorbeeld via venv of conda. Zo voorkom je dat pakketten met elkaar botsen.
Installeer Backtrader met pip install backtrader. Voor data kun je gratis bronnen gebruiken, zoals Yahoo Finance via yfinance, of betaalde data van brokers zoals Interactive Brokers of LYNX. Zorg dat je een API-key klaar hebt liggen als je met live data gaat werken.
Je hebt ook een code-editor nodig, bijvoorbeeld VS Code of PyCharm. Zorg dat je vertrouwd bent met de basiscommando’s: bestanden openen, code runnen, fouten lezen.
Tijdens het opzetten van je omgeving ben je ongeveer 15 tot 30 minuten kwijt, afhankelijk van je ervaring. Veelgemaakte fouten: vergeten een virtuele omgeving aan te maken, of verkeerde Python-versies gebruiken die conflicten geven met Backtrader. Verder is het handig om een mapstructuur te bedenken. Houd het simpel: een map strategies voor je strategiebestanden, een map data voor je CSV-bestanden, en een map results voor je backtest-outputs. Dit scheelt later enorm veel zoekwerk.
Stap 1: Zet je data op orde
Backtrader werkt het beste met tijdreeksen in CSV-formaat. Zorg dat je bestanden er zo uitzien: datum, open, high, low, close, volume. Gebruik ISO-datumformaat (YYYY-MM-DD). Voorbeeld: 2023-01-01,100.5,101.2,99.8,100.1,1000000.
Als je data van een broker haalt, controleer dan of de tijdzone klopt. Veel brokers leveren UTC, maar je handelt in lokale tijd. Verschil van 1 uur kan al voor verkeerde signalen zorgen.
Laad je data in Backtrader met de GenericCSVData-klas. Stel de kolomnummers in: dataname='data/aapl.csv', dtformat='%Y-%m-%d', openinterest=-1.
Als je intraday-data gebruikt, pas dan datetime aan naar %Y-%m-%d %H:%M:%S. Voorbeeld: een 5-minutenchart van de AEX-index. Tijdens het laden ben je ongeveer 5 minuten kwijt. Veelgemaakte fouten: verkeerde datumformaat, of vergeten de headerrij te skippen (gebruik headers=False als je geen header hebt).
Test je data met een simpele plot. Gebruik de backtrader.plot()-functie om te zien of de candlesticks kloppen.
Als de grafiek er vreemd uitziet, controleer dan de volgorde van de kolommen. Dit voorkomt dat je later met foute signalen zit.
Stap 2: Bouw een herbruikbare strategie-klasse
Een strategie in Backtrader is een klasse die erven van bt.Strategy. Je definieert parameters, indicatoren en de logica voor entry en exit. Wil je weten waarom VectorBT sneller is dan Backtrader voor je backtesting?
Begin met een simpele strategie: een moving average crossover. Gebruik twee moving averages: een korte (bijv. 10) en een lange (bijv. 30).
class MovingAverageCross(bt.Strategy):
params = (
('short_period', 10),
('long_period', 30),
('size', 100), # aantal aandelen per trade
)
def __init__(self):
self.sma_short = bt.indicators.SMA(self.data.close, period=self.p.short_period)
self.sma_long = bt.indicators.SMA(self.data.close, period=self.p.long_period)
self.crossover = bt.indicators.CrossOver(self.sma_short, self.sma_long)
Als de korte boven de lange komt, koop je; als hij eronder komt, verkoop je.
Maak de parameters instelbaar via de constructor. Voorbeeld: Deze aanpak maakt je strategie herbruikbaar. Je kunt later makkelijk de periodes aanpassen zonder de code te herschrijven. Tijd om deze klasse te bouwen: ongeveer 20 minuten.
Veelgemaakte fouten: indicatoren niet correct initialiseren, of vergeten de params te gebruiken waardoor je hardcoded waarden krijgt. Voeg een log toe om trades te volgen.
Gebruik self.log(f'Order, price={price}') om elke actie te noteren. Dit helpt bij het debuggen en bij het controleren of je risicomanagement klopt. Zorg dat je geen overbodige prints gebruikt; houd het overzichtelijk.
Stap 3: Voeg risicomanagement toe
Een strategie zonder risicomanagement is als autorijden zonder gordel. Voeg stop-loss en take-profit toe. Gebruik een eenvoudige stop-loss op basis van een percentage, bijvoorbeeld 2% van de entry-prijs.
Voorbeeld: als je koopt op €100, plaats je een stop-loss op €98.
Take-profit kun je instellen op 4%: verkoop bij €104. Gebruik de self.buy() en self.sell() methoden met de juiste parameters. Voorbeeld:
def next(self):
if self.crossover > 0: # korte MA kruist omhoog
self.buy(size=self.p.size, exectype=bt.Order.StopLimit, price=self.data.close[0] * 1.01)
self.stop_loss = self.data.close[0] * 0.98
self.take_profit = self.data.close[0] * 1.04
elif self.crossover < 0: # korte MA kruist omlaag
self.sell(size=self.p.size)
Let op: stop-loss en take-profit kun je dynamisch aanpassen op basis van de volatiliteit. Gebruik de Average True Range (ATR) voor een flexibeler stop-niveau. Voorbeeld: stop = entry - 1.5 * ATR.
Dit voorkomt dat je te snel uitgestopt wordt bij normale schommelingen. Tijd voor deze stap: 15 minuten.
Veelgemaakte fouten: stop-loss vergeten, of een te strakke stop instellen waardoor je constant uitgestopt wordt. Verwerk je risicomanagement in een aparte functie, bijvoorbeeld calculate_position_size(). Gebruik de Kelly-criterium of een eenvoudige procentuele benadering. Voorbeeld: risico per trade is 1% van je totale kapitaal.
Als je €10.000 hebt, riskeer je €100 per trade. Bereken het aantal aandelen: €100 / (entry - stop). Dit houdt je risico constant en herbruikbaar.
Stap 4: Test en optimaliseer je strategie
Backtesten is je beste leermeester. Volg onze Backtrader handleiding om je eerste backtest script te schrijven met de bt.Cerebro()-engine.
Voeg je data toe, stel het startkapitaal in (bijv. €10.000), en voeg je strategie toe. Voorbeeld: Optimaliseren doe je met de optstrategy-methode. Geef ranges op voor je parameters, bijvoorbeeld short_period van 5 tot 20, long_period van 20 tot 50.
cerebro = bt.Cerebro()
cerebro.addstrategy(MovingAverageCross)
cerebro.adddata(data)
cerebro.broker.setcash(10000)
cerebro.broker.setcommission(commission=0.001) # 0.1% per trade
cerebro.run()
cerebro.plot()
Backtrader draait dan honderden runs en toont de beste combinatie. Let op: te veel parameters optimaliseren leidt tot overfitting.
Beperk je tot 2 à 3 parameters. Tijd voor een volledige backtest: 10 minuten.
Optimalisatie kan langer duren, afhankelijk van je hardware. Veelgemaakte fouten: vergeten commissies mee te nemen, of te werken met toekomstige data (look-ahead bias). Controleer altijd of je resultaten realistisch zijn. Gebruik een out-of-sample periode om je strategie te valideren.
Bijvoorbeeld: backtest op 2018-2022, valideer op 2023. Dit geeft je meer vertrouwen in de robuustheid.
Verificatie-checklist
- Data is correct geladen en de datumformaat klopt.
- Strategie-klasse erft van
bt.Strategyen gebruiktparams. - Indicatoren zijn correct geïnitialiseerd en gebruikt.
- Risicomanagement (stop-loss, take-profit) is toegevoegd en getest.
- Position sizing is gebaseerd op een vast risicopercentage.
- Backtest is uitgevoerd met commissies en realistische spreads.
- Optimalisatie is beperkt tot 2 à 3 parameters om overfitting te voorkomen.
- Resultaten zijn geplot en visueel gecontroleerd.
- Een out-of-sample periode is gebruikt voor validatie.
- De strategie is opgeslagen als herbruikbaar bestand, klaar voor toekomstige aanpassingen.
Met deze checklist ben je er bijna. Als alles klopt, kun je je strategie koppelen aan een broker API, zoals Interactive Brokers of LYNX, voor live trading.
Begin klein, monitor je resultaten, en schaal langzaam op. Gebruik de juiste Python libraries voor je trading architectuur om een solide basis te bouwen voor algoritmische trading.
