De Kalman Filter implementeren voor ruisonderdrukking in koersen
Je kent dat gevoel wel: je kijkt naar een koerslijn en die is ronduit chaotisch.
Pieken, dalen, rare uitschieters. Je probeert patronen te vinden, maar de ruis is overal. Als je een algoritmische bot bouwt in Python, wil je niet handelen op elke ruispiek.
Je wilt het echte signaal zien. De Kalman filter is je beste vriend hier.
Het is een slimme rekenmethode die ruis uit je data filtert, zonder het echte trend te verliezen.
Denk er maar aan als een GPS die constant je locatie bijstelt: hij voorspelt waar je bent, meet waar je bent, en past zijn schatting aan. Zo werkt het ook met koersen.
Wat is de Kalman filter?
De Kalman filter is een algoritme dat ontwikkeld is door Rudolf E. Kalman in 1960.
Het is een wiskundige methode om schattingen te maken van een onbekende toestand, zoals de 'ware' prijs van een aandeel of crypto, terwijl je metingen (koersen) hebt die vol ruis zitten. Het is geen magie, maar een iteratief proces: je voorspelt, je meet, en je past aan. In de wereld van algoritmische trading bots wordt het gebruikt om signaalruisverhouding te verbeteren, zodat je bot niet reageert op elke willekeurige prijsbeweging.
Waarom is dit relevant voor jou? Omdat elke broker API (zoals die van Interactive Brokers, Binance of Kraken) data levert die ruis bevat.
Je backtests moeten robuust zijn. Als je een simple moving average gebruikt, heb je altijd vertraging.
De Kalman filter is adaptief: hij reageert sneller op sterke trends en filtert kleine schommelingen weg. Dit betekent minder false positives in je entry- en exit-signalen. Stel je voor: je bouwt een bot in Python met libraries als numpy en pandas. Je haalt 1-minuut candles op via de API.
Je wilt een clean signaal voor je trendindicator. De Kalman filter geeft je een geschatte prijs die soepeler is dan de raw data, maar nog steeds dichtbij de realiteit. Het is een kerncomponent voor risicomanagement, omdat het je helpt om emotionele beslissingen (van de bot) te vermijden.
Hoe werkt de Kalman filter?
De filter werkt in een cyclus: voorspelling en update. Je hebt een model van hoe de prijs zich beweegt (bijvoorbeeld een random walk), en je hebt metingen (de koers).
Het algoritme combineert beide met onzekerheid. De kern is de Kalman gain: een getal tussen 0 en 1 dat bepaalt hoeveel je vertrouwt op je meting versus je voorspelling.
Hoe meer ruis in de meting, hoe meer je op je model leunt. In Python implementeer je dit met arrays en matrices. Je begint met een initiële schatting van de prijs en de onzekerheid (covariantie). Dan draai je de cyclus voor elke nieuwe candle.
Voorspelling stap (predictie)
Je kunt het zien als een feedback-loop die constant bijstelt. Voor algoritmische trading bots is dit cruciaal: je vermijdt dat je bot te snel reageert op een enkele spike van een broker API, wat vaak tot overtrading leidt.
Stel je voor dat je een bot bouwt voor EUR/USD. De API levert een prijs van 1.0850, maar er zit micro-ruis op. Je model voorspelt 1.0848 op basis van de vorige stap.
De filter berekent een nieuwe schatting van 1.0849, afhankelijk van de gain. Dit proces herhaal je voor elke tick, wat resulteert in een gladdere lijn die je kunt gebruiken voor signalen in je backtest.
In de voorspelling stap gebruik je een model om de volgende toestand te schatten.
Voor koersdata is een eenvoudig model vaak een random walk: de volgende prijs is gelijk aan de vorige prijs, plus een beetje ruis. In code: je neemt je vorige schatting en past een transitie-matrix toe, bijvoorbeeld [1] voor een simpele prijs, met een procesruis (Q) die de onzekerheid in het model weergeeft. Waarom belangrijk?
Update stap (fusie met metingen)
Omdat dit je basis is. Zonder voorspelling heb je geen referentie.
In Python, met numpy, ziet dit eruit als een simpele vermenigvuldiging: prev_estimate * transition_matrix + noise.
Voor een trading bot betekent dit dat je een baseline hebt voor je volgende candle, voordat je de echte data van de broker ziet. Realistisch blijven: je procesmodel moet niet te complex zijn.
Voor crypto-koersen is een random walk redelijk; voor aandelen met sterke trends kun je een kleine drift toevoegen (bijv. 0.01% per candle). Test dit in je backtest met historical data van je broker, en pas de procesruis aan op basis van de volatiliteit. Te veel ruis en je filter is te traag; te weinig en je volgt ruis. De update stap is waar de magie gebeurt: je neemt je voorspelling en fuseert die met de nieuwe meting (de daadwerkelijke koers van je API).
Je berekent de innovatie (het verschil tussen meting en voorspelling) en past je schatting aan.
Dit is de fusie: je combineert model en data op een optimale manier. In de praktijk: je haalt een candle op van 1.0852, je voorspelling was 1.0849. Het verschil is 0.0003.
Kalman gain en onzekerheid
De filter past je schatting aan naar, zeg, 1.0850, afhankelijk van de Kalman gain. Hoe meer ruis in de meting (bijv. door lage liquiditeit), hoe minder je aanpast.
Voor risicomanagement is dit top: je bot handelt niet op elke uitschieter.
In Python kun je dit implementeren met een simpele loop: voor elke candle, update de state. Gebruik libraries zoals filterpy (een Python-library voor Kalman filters) om het makkelijker te maken, maar je kunt het ook vanaf scratch bouwen voor meer controle. De Kalman gain (K) is de sleutel: het is een getal dat bepaalt hoeveel je je schatting aanpast op basis van de meting.
K = P_pred / (P_pred + R), waar P_pred de onzekerheid van de voorspelling is en R de ruis van de meting. Hoe hoger R (meer ruis), hoe lager K, en dus meer vertrouwen in je model.
Onzekerheid wordt bijgehouden in covariantie-matrices. Je begint met een initiële onzekerheid (bijv.
1 voor de prijs), en past die aan in elke stap. In een trading context: als de markt rustig is (lage volatiliteit), is R klein, K hoog, en volg je de meting dichter.
Samenspel van model, ruis en initiële condities
Tijdens een crash is R groot, K laag, en blijf je bij je model. Praktisch voor je bot: tune K op basis van backtesting. Gebruik historical data van je broker (bijv. 1 jaar EUR/USD 1-minuut candles) en meet de winstgevendheid.
Als je te veel false positives hebt, verhoog R (meer gewicht aan model).
Dit is risicomanagement in actie. Het samenspel is cruciaal: je model is je theorie over hoe de markt beweegt, ruis is de chaos van de werkelijke data, en initiële condities bepalen waar je start. Een slecht model (bijv. lineaire trend voor een choppy markt) leidt tot slechte schattingen, zelfs met goede ruisinstellingen.
Initiële condities: begin met een schatting die dicht bij de eerste candle ligt, en een onzekerheid die past bij de markt (bijv. 0.1% van de prijs voor stabiele aandelen).
Ruis: meet de historische volatiliteit via je API en pas R aan, of bereken zelf de RSI indicator om je filter-signalen te valideren.
Voor Python bots: gebruik pandas om ruis te berekenen (std dev van returns). Tip: verwar particle filters niet met Kalman filters. Bron 1 (An Uncommon Lab, 2013) beschrijft een particle filter voor probabilistische schattingen (bijv. land-prioriteiten of restaurant-kansen), wat handig is voor Monte Carlo-simulaties in trading, maar niet hetzelfde als de deterministische Kalman update. Gebruik Kalman voor ruisonderdrukking; particle filters voor complexe niet-lineaire modellen als je advanced wilt gaan.
Praktische implementatie in Python voor trading bots
Laten we het concreet maken: je bouwt een Kalman filter voor een trading bot die werkt met een broker API zoals Alpaca of Binance. Je hebt Python nodig, numpy, en visualiseer je koersgrafieken in Python met filterpy (gratis op GitHub).
Stap 1: haal data op via de API (bijv. 1000 candles voor backtesting).
Stap 2: initialiseer je state: prijs-schatting = eerste candle, onzekerheid = 0.01 (1%). Code-voorbeeld in pseudo-Python: import numpy als np; Q = 0.0001 (procesruis); R = 0.001 (meterruis); P = 1.0 (initiële onzekerheid); x = eerste_prijs. Voor elke candle: voorspel x_pred = x; P_pred = P + Q; K = P_pred / (P_pred + R); update x = x_pred + K * (meting - x_pred); P = (1 - K) * P_pred.
Test dit in een backtest: loop over historical data, pas de filter toe, en gebruik de geschatte prijs voor je signalen (bijv. crossover met een moving average). Meet prestaties met metrics zoals Sharpe ratio of max drawdown.
Voor risicomanagement: voeg een stop-loss toe op basis van de gefilterde prijs, niet de raw data. Prijzen voor tools: filterpy is gratis, een VPS voor je bot kost €5-10/maand bij DigitalOcean.
Variante: Extended Kalman Filter voor niet-lineaire markten
De basis Kalman filter gaat uit van lineaire modellen, maar markten zijn niet-lineair (bijv. tijdens news events).
De Extended Kalman Filter (EKF) past niet-lineaire functies toe door lokale linearisatie. Handig voor aandelen met sterke trends of crypto met bursts. Implementatie in Python: gebruik filterpy's EKF-module.
Je definieert een niet-lineair model, bijv. x_pred = x * (1 + drift) + noise, en lineariseert met Jacobiaanse. Voor trading bots: EKF is beter voor assets met hoge volatiliteit, zoals Bitcoin.
Test met backtesting: vergelijk EKF vs. standaard Kalman op 1 jaar data van je broker.
Prijsindicaties: filterpy is gratis; voor custom development, een Python-ontwikkelaar kost €50-100/uur. Gebruik het voor risicomanagement: EKF reduceert fouten in schattingen, wat leidt tot stabielere bot-beslissingen en minder verliezen.
Praktische tips voor ruisonderdrukking in koersen
Start simpel: implementeer eerst de basis Kalman filter voor één asset, zoals EUR/USD via je broker API.
Gebruik korte paragrafen in je code-commentaren om het bij te houden. Tune parameters via grid search in je backtest: varieer Q en R van 0.0001 tot 0.01 en kijk naar winst. Realistisch model: voor aandelen, neem een random walk met drift; voor crypto, voeg extra procesruis toe vanwege volatiliteit. Check altijd de API-limieten van je broker (bijv. rate limits) om data-gaps te vermijden, wat je filter kan verstoren.
Veelgemaakte fouten: vergeet de update stap niet—alleen voorspellen leidt tot drift. Verwar niet met particle filters (Bron 1 is voor probabilistische schattingen, niet ruisonderdrukking).
Gebruik Kalman gain voor adaptieve afweging: in rustige markten, vertrouw meer op metingen; in chaos, op je model.
Eindelijk: combineer met andere tools. Gebruik de gefilterde prijs voor je geavanceerde RSI berekeningen in Python. Voor risicomanagement: stel een max drawdown in van 5% op je bot. Experimenteer met een demo-account voordat je live gaat—je wilt geen kapitaal verliezen aan ruis.
