Wat is de 'Stationarity' van data en waarom is het belangrijk voor backtests?
Je hebt een strategie gebouwd in Python, je backtest ziet er prachtig uit met een winst van 20% in drie maanden, en je broker-API is al ingesteld op Interactive Brokers of Alpaca. Maar als je die bot live zet, stort alles in. Waarom?
Omdat de markt veranderd is en jouw data dat niet deed vermoeden. Dit probleem begint vaak bij stationarity, of het gebrek daaraan. Stationarity klinkt als een saai statistisch termietje, maar het is het fundament van elke betrouwbare backtest.
Zonder dit concept bouw je een bot die in het verleden werkt, maar in de toekomst faalt.
Laten we eens kijken wat het echt betekent en hoe je het gebruikt om je algoritmische trading bots stabieler te maken.
Wat is stationarity precies?
Stel je voor dat je een treinrit maakt. Als je uit het raam kijkt en de bomen blijven even ver uit elkaar staan, heb je een stabiel beeld. Dat is stationarity.
In data-termen betekent het dat de statistische eigenschappen van een tijdreeks – zoals het gemiddelde en de standaardafwijking – in de tijd niet veranderen. De trein beweegt, maar het landschap blijft consistent. Als een tijdreeks niet stationair is, verandert het gemiddelde of de variantie na verloop van tijd.
Denk aan een aandeel dat in 2020 gemiddeld €50 was, in 2023 plots €150 werd, en in 2024 weer daalde naar €80.
Je bot die gebaseerd is op de gemiddelde prijs van 2020 zal nu volledig ontregeld raken. De markt is niet meer hetzelfde. Voor algoritmische trading bots is dit cruciaal. Je backtest gebruikt historische data om toekomstige prestaties te voorspellen.
Als de onderliggende data niet stationair is, zijn je berekeningen – zoals moving averages of RSI-waardes – niet betrouwbaar. Je bot handelt op basis van verouderde patronen die niet meer bestaan.
Waarom het je backtest kan vernietigen
Stel je voor dat je een mean-reversion strategie bouwt op basis van de S&P 500. Je neemt data van 2010 tot 2020 en ziet dat de index altijd terugkeert naar zijn gemiddelde.
Je backtest toont een nette winst van 15% per jaar. Maar vanaf 2020 verandert het marktgedrag door inflatie en rentewijzigingen. De index blijft stijgen zonder terug te keren naar dat oude gemiddelde.
Je bot gaat short op een stijgende markt en verliest €5.000 in de eerste week.
Dit gebeurt omdat de tijdreeks niet stationair was. Het gemiddelde en de variantie zijn verschoven. Je risicomanagement modellen, zoals Value at Risk (VaR), berekenen verliezen op basis van oude data en onderschatten de werkelijke blootstelling.
Je broker-API stuurt order na order de markt in, gebaseerd op een model dat niet meer klopt. Backtests zijn geen glazen bol; ze zijn gereedschappen om hypotheses te testen.
Als de data niet stationair is, test je een hypothese die al achterhaald is. Het resultaat?
Een bot die in de live-omgeving floppt, ondanks een perfecte backtest. Je moet dus altijd checken of je data stabiel genoeg is voordat je gaat traden.
Hoe je stationarity test en herkent
Gelukkig hoef je niet blind te varen. Er zijn eenvoudige tests om stationarity te controleren in je Python-omgeving.
De meest bekende is de Augmented Dickey-Fuller (ADF) test, beschikbaar in libraries zoals statsmodels. Als de p-waarde lager is dan 0.05, is je tijdreeks waarschijnlijk stationair.
Een hogere waarde betekent dat je moet differëntiëren of de data moet transformeren. Visualisatie is je eerste stap. Plot je prijsdata en kijk naar trends. Stijgt de lijn gestaag of fluctueert hij wild?
Gebruik een rolling mean en rolling standaardafwijking – bijvoorbeeld over 20 periods – om veranderingen te zien.
Als de lijnen niet stabiel zijn, is je data niet stationair. In Python kun je dit makkelijk doen met pandas en matplotlib. Specifieke voorbeelden uit de trading-wereld: voor een EUR/USD pair op Interactive Brokers, check je de historische data met point-in-time correctheid via de API.
Als de wisselkoers een sterke trend heeft (bijvoorbeeld door ECB-beleid), is de tijdreeks niet stationair. Differëntieer dan de data: bereken het verschil tussen opeenvolgende prijzen.
Modellen die rekening houden met non-stationarity
Dit maakt de reeks vaak stationair en geschikt voor modellen zoals ARIMA of machine learning bots.
Niet elke strategie vereist volledige stationarity. Sommige modellen zijn gebouwd om met trends om te gaan. Een voorbeeld is differëntiëren, zoals hierboven genoemd.
Voor een Python-bot die op prijsmomenten handelt, kun je de log-return berekenen in plaats van ruwe prijzen. Dit maakt de data vaak stationairder en beter voor voorspellingen.
Een ander model is de ARIMA (AutoRegressive Integrated Moving Average), die integratie gebruikt om non-stationarity te behandelen.
Voor risicomanagement kun je GARCH-modellen toepassen, die schommelingen in variantie meenemen – ideaal voor volatiliteitstrading op brokers zoals Degiro of Plus500. Prijzen voor API-toegang bij deze brokers variëren van €0 tot €10 per maand, afhankelijk van het volume.
Als je een bot bouwt voor aandelen zoals Tesla (TSLA), onthoud dan dat prijzen niet stationair zijn door nieuwsgebeurtenissen. Simuleer de invloed van nieuws-events op historische backtests door een rolling window van 60 dagen te gebruiken om recente data te wegen. Dit voorkomt dat oude, irrelevante data je model verpest. Combineer dit met risicomanagement tools zoals stop-losses op 2% van je kapitaal om verliezen te beperken.
Praktische tips voor je trading bots
Start altijd met een grondige check van je data voordat je een backtest draait. Download historische data via de API van je broker – bijvoorbeeld Alpha Vantage of Yahoo Finance voor Python-scripts – en begrijp het belang van tick data vs minute data voor je backtest, en test op stationarity met ADF.
Als het mis is, pas differëntiëring toe of gebruik log-returns. Dit kan je backtest betrouwbaarder maken en teleurstellingen voorkomen.
Bouw je bot in Python met libraries zoals pandas, numpy en scikit-learn. Test je strategie op out-of-sample data: split je dataset in 70% voor training en 30% voor validatie. Als de prestaties op de testset afwijken, is je model waarschijnlijk niet robust genoeg door non-stationarity.
Gebruik een walk-forward analyse om te simuleren hoe de bot in real-time zou presteren. Voor risicomanagement, stel limieten in op je broker-API. Bijvoorbeeld, maximum 5% van je kapitaal per trade en een dagelijks verlieslimiet van €500. Monitor je bot continu met dashboards in Python (bijv.
Streamlit) om veranderingen in marktgedrag te detecteren. Onthoud: geen enkele backtest is perfect, maar met stationarity in je achterhoofd bouw je bots die langer meegaan.
