Met Machine Learning een Kristallen Bol ontwikkelen
Is AI magie of de nieuwe steen der wijzen?
Direct naar de laatste versie van het model
In het kader van mijn zoektocht naar antwoord op de vraag Is AI magie of zijn het gewoon wat regels Python code? Dacht ik waarom wagen we niet een poging om de heilige graal te ontdekken/ontwikkelen in de aandelenhandel. Met al die beschikbare AI kennis die voor het oprapen ligt moet het toch te doen zijn om een aandelenkoers voorspeller te ontwikkelen?!
In dit blogitem houd ik wekelijks bij of het model vorderingen maakt. Het doel is vergelijkbaar met de zoektocht naar de "steen der wijzen" die gewone metalen in goud zou kunnen veranderen, een doel dat uiteindelijk onbereikbaar bleek. Maar... veel mensen zoeken naar de "heilige graal" van koersvoorspelling, een model dat perfecte voorspellingen kan doen, wat ook onbereikbaar lijkt gezien de inherente onvoorspelbaarheid van de financiële markten. Bedenk echter dat hoewel perfecte voorspellingen onbereikbaar zijn, AI-modellen nuttige inzichten kunnen bieden en helpen bij besluitvorming, zelfs als ze niet altijd perfect zijn. We zullen zien hoe ver we komen! Oh en... Rome is ook niet op één dag gebouwd.
Als je zo dit blogitem doorleest dan krijg je misschien het idee dat ik een Quant ben, een quantitative analist. Ik moet echter bekennen dat een flink aandeel van mijn kennis op gebied van Machine learning te danken is aan mijn gebruik van AI hulpmiddelen zoals Github co-pilot. Dus bij het bouwen van de kristallen bol is AI al een geweldig hulpmiddel!. Ik denk dat je wel 50% aan kennis en efficiency verdient door er handig gebruik van te maken. De stelling dat je beter niet meer kunt leren programmeren lijkt mij steeds meer juist als je bedenkt dat we nog maar in het prille begin van het AI tijdperk zitten.
Het idee
Met behulp van Python, AI-modellen, gratis beschikbare data en wat coderen de koers van
morgen voorspellen voor een specifiek aandeel (of ETF).
Als je het model chronologisch wilt volgen kan je best bij week 7 beginnen met lezen.

Een nieuwe week, een nieuw model dus nieuwe kansen!
Reacties zijn van harte welkom 😊.
The missing link, week 16
Ik heb de ontbrekende schakel gefixt. Samen met mijn CodeBot 3000 heb ik eindelijk het verband
blootgelegd tussen Trump-quotes en economische paniekgolven. Geniet ervan — en gebruik het wijs!
The Trump Economic
Predictor.
Versie 6 (laatste), week 15
Het model is opnieuw getraind maar de uitkomst staat wel vast. Het voorspellen van de koersen
is ondoenlijk. Vooral in deze roerige tijden is er geen ratio maar drijft de koers op emotie.
De enige manier om (veel) geld te verdienen in deze volatiele markt is om direct te reageren
op fluctuaties. Maar... op basis van gratis koersinformatie loop je dan altijd achter de feiten aan.
Conclusie: Een model bouwen met hulp van AI is prima te doen. Het voorspellen van de koers blijft
(zoals verwacht) echter een ander verhaal!
Versie 6, week 11
De lat heb ik wat lager gelegd door in plaats van de koers van een index de koers van een enkel aandeel te voorspellen. Ik heb gekozen voor een relatief stabiel aandeel binnen de AEX-index namelijk Ahold. Maar zelfs deze stabiele aandelen ontkomen niet aan de grote dagverschillen in deze roerige financiële tijden. Het is niet de makkelijkste tijd om je model uit te proberen 😉
Er is ten opzichte van versie 5 niet zo veel veranderd aan het model. Het model is nu getraind op de data van het aandeel Ahold. Voor het maken van de afbeeldingen heb ik de hulp ingezet van Google Gemini, ook daar ben ik wel over te spreken vwb. de ondersteuning op het gebied van Python code.
Je bent automatiseerder of niet...


Ik heb Google Gemini de training code van versie 6 laten beoordelen en naast het aanhalen van
veel sterke punten geeft Gemini ook een aantal Verbeteringssuggesties:
Hyperparameter Tuning: Overweeg het gebruik van andere tuners zoals BayesianOptimization of Hyperband
voor mogelijk betere resultaten.
Model Evaluatie: Overweeg het gebruik van cross-validatie om de robuustheid van het model te beoordelen.
Gebruik van Logging: Voeg logging toe. Dit is erg belangrijk voor het debuggen en monitoren van je code.
Het is nog wel te vroeg om ook geautomatiseerd transacties uit te zetten op basis van de voorspelling 😉
De code van versie 6 is natuurlijk ook beschikbaar via GitHub. "Als iedereen samen vooruitgaat, dan zorgt succes voor zichzelf." --Henry Ford.
Versie 5, week 10
Nieuws sentiment toegevoegd
Om het dagelijkse sentiment van relevant financieel nieuws een plek te geven in het voorspel model heb ik een module
get_news toegevoegd. Deze module haalt de voor de 'ticker' relevante nieuws items op. Helaas is de gratis
nieuws feed beperkt tot de titels van het nieuws. Toch heb ik van deze titels het sentiment bepaald.
Sentiment varieert van -1 tot +1 om te kunnen gebruiken in het model.
Per dag wordt vervolgens het gemiddelde sentiment bepaald en toegevoegd aan de overige indicatoren.
Een beter resultaat kan worden behaald als het sentiment kan worden bepaald van de complete nieuws artikelen.
Ik ben op dit moment nog niet zo ver om een betaald abonnement aan te schaffen.
Residuele verbindingen
Op advies van claude.ai zijn residuele verbindingen aan het model toegevoegd. Bij residuele verbindingen laat je informatie van een eerdere laag direct "overslaan" naar een latere laag. Je voegt dus de output van een eerdere laag direct toe aan de output van een latere laag. De voordelen voor een aandelenkoers-voorspellingsmodel zijn volgens claude.ai: voorkomt verdwijnende gradiënten, behoudt van originele informatie, het verbetert de training en verschillende tijdschalen en patronen kunnen beter worden gecombineerd.
Claude.ai model beoordeling
Ik heb claude.ai het trainingscript laten beoordelen en dit was de bevinding:
Ik heb je model voor koersvoorspelling bestudeerd en vind het over het algemeen goed opgezet. Je gebruikt LSTM's,
attention mechanismen, en technische indicatoren, wat allemaal goede keuzes zijn voor dit probleem.
Sterke punten:
Training met versie 5
Laatste training model versie 5 met de volgende parameters:
- weight: -0.2
- rows: 2000
- thresh: 3
- seq_length: 30
- noise: 0.01
- dropout: 0.5
- learning_rate: 0.0001
- test_size: 0.2
- max_trials: 10
- executions_per_trial: 2
- patience: 3
- factor: 0.1
- min_lr: 1e-06
- epochs: 100
- batch_size: 64
Onder een afbeelding van de nu gebruikte variatie en versie 5.

Voorspelling vs. Realiteit V5
Hieronder een aantal dagen voorspelling en realiteit van het huidige model (versie 5). De gebruikte data is van de ETF DGTL.MI, zie deze Yahoo link voor de actuele waarden.
| Datum | Voorspeld | Werkelijk | Bijzonderheden |
|---|---|---|---|
| 250303 | EUR 9,99 | EUR 10,28 | |
| 250304 | EUR 9,95 | EUR 9,79 | |
| 250305 | EUR 9,87 | EUR 9,73 | |
| 250306 | EUR 9,86 | EUR 9,77 | |
| 250307 | EUR 9,98 | EUR 9,36 |
Onder een afbeelding van de voorspelling vs. de werkelijkheid. Te zien is dat een heftige gebeurtenis niet te voorspellen is.
Een voorlopige conclusie: Een training bouwen, met behulp van AI, die volgens de theorie best hout snijdt is goed te doen. Daarmee een voorpelling genereren die in de buurt komt van de werkelijkheid lukt ook. Maar... als er een meer extreme gebeurtenis plaats vindt, zoals afgelopen week, dan slaan we de plank flink mis. Daarom... ook met versie 5 van het model gaan we nog niet rijk worden 😞

Code beschikbaar via GitHub. "Als iedereen samen vooruitgaat, dan zorgt succes voor zichzelf." --Henry Ford.
Versie 4, week 9
SHAP (SHapley Additive exPlanations)
Met behulp van SHAP (SHapley Additive exPlanations) ben ik in het huidige model terug gegaan naar een 11-tal technische indicatoren. De SHAP verklaring van het effect van de verschillende indicatoren wordt weergegeven in onderstaande grafiek. Door deze vereenvoudiging wordt de voorspelling wat beter verklaarbaar.

Hyper parameters, zoeken naar de speld in de hooiberg
Daarnaast heb ik een 'loop' opgezet om de training meerdere keren aan te roepen met verschillende waarden die ik opsla in een JSON bestand. Deze loop gebruik ik om meer grip te krijgen op de vele varianten die mogelijk zijn om het model te trainen. Voor elke run uit de loop geef ik de accuraatheid weer in de vorm van een grafiek. De beste uitkomst wordt vervolgens gebruikt in het model. Onder een afbeelding van de nu gebruikte variatie.

De DeepSeek conclusie bij het beoordelen van de bovenstaande training vs. validatie grafiek laat zien dat er nog wel ruimte is voor verbetering. Het is wel zoeken naar een speld in de hooiberg om de juiste model-variatie te vinden die het best overfitting tegen gaat. Conclusie van DeepSeek: Het model leert effectief, maar er zijn tekenen van overfitting. Het is belangrijk om maatregelen te nemen om de generalisatieprestaties te verbeteren. De volgende maatregelen worden voorgesteld:
Voorspelling vs. Realiteit V4
Hieronder een aantal dagen voorspelling en realiteit van het huidige model (versie 4). De gebruikte data is van de ETF DGTL.MI, zie deze Yahoo link voor de actuele waarden.
| Datum | Slotkoers | Voorspeld dag +1 | Werkelijk | Bijzonderheden |
|---|---|---|---|---|
| 250224 | EUR 10,36 | EUR 9,54 | EUR 10,16 | De voorspelling geeft een flinke koersdaling aan. De werkelijkheid blijkt iets minder dramatisch. De richting was wel goed! |
| 250225 | EUR 10,16 | EUR 9,97 | EUR 10,38 | Richting niet juist. |
| 250226 | EUR 10,38 | EUR 9,81 | EUR 10,40 | Voorspelling dat koers fors lager wordt. Is echter €0,02 hoger gesloten. |
| 250227 | EUR 10,40 | EUR 10,03 | EUR 10,21 | De voorspelling na implementatie van de DeepSeek aanbevelingen. De richting is goed maar de daling is in werkelijkheid iets minder groot. |
De koers juist voorspellen is met deze versie nog niet mogelijk. Voorspellen of de koers daalt of stijgt de volgende werkdag lijkt een meer realistisch doel. In versie 4 heb ik ook de de deepseek aanbevelingen uitgeprobeerd om te kijken of dat de uitkomst beter maakt. De voorspelling van de slotkoers van 28 feb is uitgevoerd met deze aanbevelingen in de code. Het model is opnieuw getraind met de aanbevolen waarden. Onder een afbeelding van de accuraatheid na de DeepSeek aanbevelingen te hebben geïmplementeerd.

De DeepSeek beoordeling van de grafiek. De grafiek toont de training en validatieverlies (loss) over verschillende epochs. Hier zijn enkele observaties en beoordelingen:
Code V4 beschkbaar via GitHub
Vanaf deze versie vind ik de code netjes en bruikbaar genoeg om deze publiekelijk te delen via GitHub. "Als iedereen samen vooruitgaat, dan zorgt succes voor zichzelf." --Henry Ford.
Versie 3, week 8
Allereerst is de dataleverancier veranderd. De gegevens worden nu opgehaald vanuit Yahoo Finance. De belangrijkste reden is dat Yahoo niet alleen US data levert maar ook data van Euronext, ook handig is dat de gewenste data in Euro's is in plaats van Dollars. Nog een voordeel is dat ook koersen van ETF's beschikbaar zijn waar ik zelf meer gebruik van maak dan van aandelenkoersen.
Als nieuwe bron van AI kennis heb ik ook Le Chat ingezet. Het Franse model dat, volgens mijn eerste indruk, niet onder doet voor ChatGPT of Deepseek. Het is alleen een stuk trager.
De volgende verbeteringen hebben te maken met het zwaarder laten wegen van de meest recente gegevens ten opzichte van gegevens die ouder zijn. Om dit te realiseren zijn de volgende verbeteringen doorgevoerd:
De gebruite features zijn nu: close, daily_return, obv, williams_r, roc, rsi, macd, adx, aroon_up, aroon_down, sma_7, ema_7, sma_14, ema_14, bollinger_high, bollinger_low, atr, keltner_high, keltner_low, cmf, cci, stoch_oscillator, tenkan_sen, kijun_sen, senkou_span_a, senkou_span_b, chikou_span, vwap, fib_236, fib_382, fib_500 en fib_618.
Een andere grote wijziging is het inzetten van een tuner, deze Keras Tuner wordt gebruikt om de beste hyperparameters te vinden. Er worden callbacks toegevoegd voor early stopping en het verlagen van de learning rate. Het beste model dat mbv de tuner is gevonden wordt geëvalueerd op de testset en vervolgens opgeslagen. Ook de scaler wordt opgeslagen voor toekomstig gebruik. Model en scaler worden vervolgens gebruikt door de voorspel functie. In de afbeelding hieronder zie je de tuner op zoek naar het beste model.

Om inzicht te krijgen in het resultaat van training en validatie om daarmee overfitting inzichtelijk te maken zijn deze waarden weergegeven in een grafiek. Als training daalt maar validatie stijgt is dat een indicatie voor overfitting. Overfitting is een ongewenst gedrag van machine learning wanneer het model nauwkeurige voorspellingen geeft voor trainingsdata, maar niet voor nieuwe data. Hieronder een voorbeeld van de weergave.

De koersen van de ETF / DGTL.MI zijn:
- SLOTKOERS: van dinsdag 18 februari was € 10,87
- VOORSPELLING: voor woensdag 19 februari is Eur 10,36

De Realiteit (woensdag 19 feb)
????? morgen verder
Versie 1, week 7
De Data
Om het leuk te houden willen we alle gebruikte data gratis beschikbaar hebben.
Mocht, in een later stadium, het model het gewenste effect hebben en de euro’s binnen stromen
dan is betalen voor de data natuurlijk geen probleem!
De historische aandelen data halen we op vanaf financialmodeling.
Deze levert 5 jaar historische koersdata. Daarnaast willen we zoveel als mogelijk
aanvullende economische data toevoegen om het model met zoveel mogelijk relevante gegevens
te ‘voeden’. Dit kan met de Python Technical Analysis Library.
Een aantal voorbeelden die we inzetten in ons model zijn:
• On-Balance Volume (OBV) → Een indicator die het volume relateert aan prijsveranderingen.
• Williams %R → Een momentumindicator die overkochte en oversold condities meet.
• Rate of Change (ROC) → Meet de procentuele verandering in prijs over een bepaalde periode.
• Relative Strength Index (RSI) → Een momentumindicator die de snelheid en verandering van
prijsbewegingen meet.
• Moving Average Convergence Divergence (MACD) → Een trendvolgende momentumindicator.
• Bollinger Bands → Een volatiliteitsindicator die een boven- en onderband rond een
voortschrijdend gemiddelde plaatst.
• Average Directional Index (ADX) → Meet de sterkte van een trend.
• Chaikin Money Flow (CMF) → Combineert prijs en volume om de geldstroom te meten.
• Commodity Channel Index (CCI) → Meet de afwijking van de prijs ten opzichte van het statistisch
gemiddelde.
• Stochastic Oscillator → Een momentumindicator die de sluitingsprijs vergelijkt met het prijsbereik
over een bepaalde periode.
• Average True Range (ATR) → Meet de volatiliteit door het bereik van prijsbewegingen te analyseren.
• Aroon Indicator → Identificeert trendveranderingen en de sterkte van een trend.
• Keltner Channel High → Een volatiliteitsindicator die een bovenband rond een voortschrijdend
gemiddelde plaatst, gebaseerd op de gemiddelde true range (ATR).
• Keltner Channel Low → Een volatiliteitsindicator die een onderband rond een voortschrijdend
gemiddelde plaatst, gebaseerd op de gemiddelde true range (ATR).
• Average True Range (ATR) → Een volatiliteitsindicator die het gemiddelde
van de true range over een bepaalde periode meet.

Het Proces
1. Als we de data binnen hebben kan het echte werk beginnen! Voor het gemak en latere visuele
validatie slaan we de data op in een CSV. Als blijkt dat het model goed bruikbaar is dan
volgt in een volgende versie het vastleggen van de data in een database zodat we zelf nog
langere historie kunnen gaan vormen.
2. Voor het gebruik binnen de applicatie plaatsen we de data in een Pandas Dataframe
vergelijkbaar met een tabel met rijen en kolommen.
3. Dan splitsen we de data in een deel voor training en een deel, van 100 dagen, voor testen.
4. We schalen de data zodat het bruikbaar is voor de computer. Oftewel we normaliseren de
waarden binnen een bepaald bereik (standaard tussen 0 en 1).
Waarom schalen inzetten?
• Verbetering van machine learning prestaties
• Vermijden van dominantie door grote getallen
• Nuttig voor neurale
5. Nu gaan we het AI-model definiëren om onze voorspelling vorm te geven.
In ons geval is dat een neuronaal netwerk met behulp van Keras en TensorFlow,
specifiek een Long Short Term Memory (LSTM)-gebaseerd model voor tijdreeksvoorspellingen,
zoals het voorspellen van aandelenkoersen.
Wat doet het?
• Het neemt tijdreeksen als input (bijvoorbeeld historische aandelenprijzen).
• Het gebruikt een LSTM-laag om patronen en trends in de tijdreeks te leren.
• Het geeft een voorspelling als output, bijvoorbeeld de aandelenprijs van morgen.
6. Het bovenstaande model zetten we in om het te trainen met de train-dataset.
Doel is de patronen in de gegevens te onderkennen en ervan te leren.
• Het doet dit 50 keer (aantal epochs).
• In elke epoch verwerkt het model een bepaald aantal batches (steps_per_epoch).
• Na elke epoch wordt de validatiedataset (test_dataset) gebruikt om te zien hoe goed het model
presteert.
7 Nu gaan we met het test-deel van de data bekijken hoe goed ons model is in het voorspellen van de koers.
8. De uitkomst van deze voorspelling test wordt weergegeven in 2 waarden als mate van afwijking:
Mean Squared Error (MSE) is een maat voor de gemiddelde kwadratische afwijking tussen de voorspellingen
van je model en de werkelijke waarden; 0.4970483243207762
Mean Absolute Error (MAE) berekent de gemiddelde absolute afwijking tussen de
voorspellingen en de werkelijke waarden, zonder dat grotere fouten zwaarder worden
gewogen zoals bij de MSE; 0.5616767144227245
9. In ons geval is de koers van AHOLD genomen als training en testdata.
We weten dat de koers momenteel zo rond de $35,00 schommelt.
Als we deze koers gebruiken om onze afwijking te berekenen dan zien we het volgende:
De MSE van 0.497 betekent dat de gemiddelde kwadratische afwijking tussen de
voorspelde waarden en de werkelijke waarden $0.50 is. Dit is een kleine afwijking ten opzichte
van de aandelenprijs van $35,00.
Vergelijking: Als de aandelenprijs gemiddeld rond de $35,00 ligt, dan is een MSE van 0.497
relatief laag, wat betekent dat het model goed presteert. Bijvoorbeeld: een fout van $0.50
betekent dat het model gemiddeld een fout heeft van ongeveer 1.4% van de voorspelde prijs.
De MAE van 0.56 betekent dat de gemiddelde absolute afwijking tussen de voorspelde en
werkelijke waarden $0.56 EUR is. Vergelijking: Een MAE van $0.56 is ook relatief klein
als we kijken naar een aandelenkoers van $35,00, wat betekent dat de voorspellingen
meestal binnen ongeveer 1.6% van de werkelijke waarde liggen.
10. We slaan het model op zodat we het kunnen gebruiken bij onze dagelijkse voorspelling
De Output
De output van het idee is dus de heilige graal voor ons als ‘newbee day-trader’.
DE manier om snel rijk te worden met een minimale inspanning.
Oftewel vandaag de beurskoers van morgen voorspellen met ons AI-model en kopen die stocks.
(donderdag 13 feb) Het model geeft aan dat de slotprijs voor morgen $32,94 is.
Best een flinke afwijking van de koers van vandaag $35,02.
Het goede nieuws is dat als het klopt we snel veel geld (hadden) kunnen verdienen.De output van het idee is
dus de heilige graal voor ons als ‘newbee day-trader’. DE manier om snel rijk te worden met een minimale
inspanning.

Als extraatje kunnen we de voorspelde prijs ook in een grafiek (Matplot) bekijken tov
de prijs over laatste 60 dagen.

De Realiteit (vrijdag 14 feb)
Het model behoeft nog wat aanscherping en verdere training. De voorspelling zat er nu nog flink naast want
de werkelijke slotkoers was $35,90. Het model had een voorspelling gedaan van $32,94. Dat is een afwijking
van $2,96.
Versie 2 heeft een aantal verbeteringen ondergaan.
Of deze verbeteringen het gewenste resultaat leveren moet natuurlijk nog blijken.
Hier de voorspelling van het model voor de slotkoers van maandag 17 februari: $36,18.

Gebruik onderstaand formulier om te reageren op dit blog.
Onderstaand de eerdere reacies op dit blog.
| Datum | 2025-02-28 |
|---|---|
| Naam | Jos |
| Commentaar | Reageer als eerste 😉 |