Wat is 'Unsupervised Learning' en hoe vind je marktregimes?
Je kent het wel: de markt voelt soms totaal anders. De ene week is alles een feestje voor de bulls, de week erop hangt er een donkere sfeer en zakken alle posities als een kaartenhuis.
Meestal gokken we wat met patronen of kijken we naar een simpel RSI-tje. Maar wat als je deze sferen, oftewel marktregimes, objectief kunt meten?
Dat is precies waar onsupervised learning om de hoek komt kijken. Het is een manier om je data te laten praten zonder dat je het van tevoren al in een hokje moet stoppen. Ideaal voor het ontdekken van die verborgen structuren in bijvoorbeeld Bitcoin of de AEX. We bouwen vandaag een simpel scriptje in Python om deze regimes te vinden. Geen zorgen, je hoeft geen professor te zijn om dit te snappen.
Wat heb je in huis nodig?
Voordat we beginnen, check even of je spullen klaarstaan. We gaan niet moeilijk doen met dure software.
Alles wat we nodig hebben is gratis en draait op je eigen laptop. Als je een beetje kunt typen in Python, ben je er bijna.
- Python omgeving: Zorg dat Python geïnstalleerd is (versie 3.8 of hoger is prima).
- Essentiële bibliotheken: Open je terminal en draai
pip install pandas numpy scikit-learn yfinance matplotlib. Deze tools halen data en rekenen voor je. - Data bron: We gebruiken yfinance om gratis data te scoren. Je kunt ook data van je broker halen via hun API, bijvoorbeeld als je een account hebt bij Interactive Brokers of een crypto exchange zoals Binance.
- Tijd: Reken op een uurtje. De eerste keer duurt het even om alles op te zetten, daarna draai je dit in 5 minuten.
- Rekenkracht: Een simpele laptop volstaat. We doen niet aan diepgaande deep learning met gigantische datasets.
Stap 1: Data verzamelen en schoonmaken
Elk goed verhaal begint met data. We halen historische koersen op en berekenen direct de dagelijkse rendementen.
De prijs zelf zegt namelijk niet zoveel; de verandering is wat telt. We focussen hier op een bekende ticker, bijvoorbeeld 'SPY' (S&P 500) of 'BTC-USD'. Laten we een dataframe bouwen dat alleen de sluitingsprijzen en de returns bevat.
- Importeer
pandasenyfinance. - Download data voor de afgelopen 5 jaar:
data = yf.download('SPY', start='2019-01-01'). - Bereken de log returns:
data['Log_Return'] = np.log(data['Close'] / data['Close'].shift(1)). Log returns zijn vaak stabieler voor berekeningen. - Verwijder de eerste regel met
NaNwaardes.
Dit duurt ongeveer 5 minuten om te coderen. Veelgemaakte fout: Beginners gebruiken soms de simpele procentuele verandering.
Voor statistische modellen zijn log returns vaak beter omdat ze symmetrisch zijn.
Zorg ook dat je de data op orde hebt; een dataset met gaten erin geeft rare resultaten.
Stap 2: Kenmerken (Features) definiëren
Het algoritme moet weten wat het moet bekijken. We gaan het niet voeden met rauwe koersen, maar met kenmerken die het gedrag van de markt beschrijven. Denk aan volatiliteit (hoe heftig beweegt de markt?) en momentum (hoe hard gaat het?), wat essentieel is als je begrijpt wat is 'Supervised Learning' in de context van koersvoorspelling?
We maken een simpel venster van 20 dagen om deze metingen te doen.
- Voeg een kolom toe voor de standaardafwijking (volatiliteit) over 20 dagen:
data['Volatility'] = data['Log_Return'].rolling(window=20).std(). - Voeg een kolom toe voor het gemiddelde rendement over 20 dagen:
data['Momentum'] = data['Log_Return'].rolling(window=20).mean(). - Verwijder opnieuw de eerste 20 regels met
NaNwaardes (je hebt nu een historie van 20 dagen nodig). - Selecteer alleen deze twee kenmerken voor het model:
features = data[['Volatility', 'Momentum']].dropna().
Dit is een beetje de basis van quant trading. Tip: Je kunt hier creatief zijn.
Voeg bijvoorbeeld volume toe of de 'rolling correlation' met een andere asset. Houd het voor nu simpel met 2 features. Te veel features bij weinig data zorgt voor 'overfitting' (het model leert ruis in plaats van signalen).
Stap 3: Het K-Means algoritme toepassen
Hier gebeurt de magie. We gebruiken K-Means clustering.
Stel je een leeg vel voor met twee assen: horizontaal voor volatiliteit, verticaal voor momentum. Het algoritme gooit hier een aantal prikkeldraadjes op (de 'centroids') en trekt lijnen om alle punten heen. Punten die dicht bij elkaar liggen, horen bij dezelfde cluster. Wil je eerst een simpel lineair regressiemodel bouwen voor prijsvoorspelling voordat je met clustering aan de slag gaat?
- Importeer
KMeansuitsklearn.cluster. - Initialiseer het model:
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10). Het random_state zorgt ervoor dat jij en ik dezelfde uitkomst krijgen. - Fit het model op je features:
kmeans.fit(features). - Plak de voorspelde clusters terug in je dataframe:
data['Regime'] = kmeans.labels_(alleen voor de rijen waarvan je features had).
Dit zijn jouw marktregimes. We kiezen voor 4 clusters: Stabiel Stijgend, Stabiel Dalend, Volatiele Stijging, Volatiele Daling.
Veelgemaakte fout: Vergeet niet n_init=10 te zetten. In nieuwere versies van Scikit-Learn krijg je anders een waarschuwing, en het helpt het model stabiel te maken.
Stap 4: Visualiseren en interpreteren
Een getalletje zegt weinig. We moeten zien hoe de clusters eruitzien.
We maken een simpel scatter plot. De x-as is volatiliteit, de y-as is momentum.
- Importeer
matplotlib.pyplot. - Maak een plot:
plt.scatter(data['Volatility'], data['Momentum'], c=data['Regime'], cmap='viridis'). - Geef de assen een naam en laat zien:
plt.show(). - Check de output. Je ziet nu groepjes punten. Bereken de gemiddelde volatiliteit en momentum per cluster om te bepalen wat welk regime betekent.
Elke kleur is een ander regime. Dit geeft je direct inzicht: welke data punten horen bij welke marktmodus? Interpretatie: Kijk naar de hoeken.
Linkeronder is waarschijnlijk 'Rustig Stijgend'. Rechtsonder is 'Paniek' (hoog volatiliteit, laag rendement).
Bovenin heb je de 'Euforie'. Dit is jouw kaart van de markt.
Stap 5: Koppelen aan je trading bot
Nu weten we de regimes. De volgende stap is actie.
- Sla de data op:
data[['Regime']].to_csv('markt_regimes.csv'). - In je bot: laad dit bestand. Als de huidige regime 'Hoog Volatiliteit' is, verlaag dan je positiegrootte (position sizing).
- Logica voorbeeld:
if current_regime == 2: risk_per_trade = 0.005(0.5% risico)else: risk_per_trade = 0.02(2% risico). - Test dit logisch na in je backtest om te zien of het de drawdown verlaagt.
Je wilt niet short gaan in een 'Rustig Stijgend' regime. Je wilt je risicomanagement aanpassen op basis van deze data. Je kunt deze labeltjes nu opslaan in een CSV en laden in je bestaande backtesting script of live bot. Let op: De markt verandert en verantwoord omgaan met AI is essentieel.
Je model moet periodiek opnieuw gedraaid worden met verse data, bijvoorbeeld elke maand. Gebruik een script dat dit automatisch doet via de API van je broker.
Verificatie-checklist
Voordat je je geld inzet, loop deze lijst even na. Een goed werkend model voelt logisch en stabiel.
- ✅ Hebben de clusters een logische verdeling? (Niet alles in één bak).
- ✅ Zijn de gemiddelden per cluster logisch? (Hoge volatiliteit bij lage returns is een slecht teken).
- ✅ Is de data schoon? (Geen
NaNwaardes meer). - ✅ Werkt je script zonder errors van start tot eind?
- ✅ Is je
random_statevastgezet voor reproduceerbaarheid? - ✅ Weet je precies wat elke cluster betekent voor je strategie?
