Bollinger Bands Indikator
Misst, ob eine Aktie relativ zu ihrer eigenen Schwankungsbreite teuer oder billig ist
Bollinger Bands bestehen aus drei Linien: einem gleitenden Durchschnitt (Mitte) und zwei Bändern darüber und darunter, die jeweils 2 Standardabweichungen entfernt liegen. Wenn der Kurs das obere Band berührt, ist die Aktie relativ „überkauft“, beim unteren Band „überverkauft“.
Mittleres Band = SMA(close, 20)
Oberes Band = Mitte + 2 × StdDev(close, 20)
Unteres Band = Mitte - 2 × StdDev(close, 20)
BB-Position = (Kurs - Unteres Band) / (Oberes Band - Unteres Band)
Die BB-Position (0 bis 1) ist das Feature, das unser Agent sieht. Wert 0 = Kurs am unteren Band (potenziell überverkauft), Wert 1 = Kurs am oberen Band (potenziell überkauft), Wert 0.5 = Kurs genau in der Mitte.
Beispiel: SAP steht bei 195€, das untere Band liegt bei 185€, das obere bei 205€.
BB-Position = (195 - 185) / (205 - 185) = 0.50 → Kurs ist genau in der Mitte der Bands.
RSI — Relative Strength Index Indikator
Misst die Geschwindigkeit und Stärke von Kursbewegungen (0-100)
Der RSI vergleicht die durchschnittlichen Gewinne mit den durchschnittlichen Verlusten über einen Zeitraum (bei uns: 9 Perioden). Ein Wert über 70 gilt als „überkauft“ (Kurs könnte fallen), unter 30 als „überverkauft“ (Kurs könnte steigen).
RS = Durchschnittlicher Gewinn / Durchschnittlicher Verlust
RSI = 100 - (100 / (1 + RS))
Unser Agent sieht den RSI normalisiert auf 0-1 (RSI/100). Bei 0.7+ ist Vorsicht beim Kauf geboten, bei 0.3- könnte ein günstiger Einstieg vorliegen.
MACD — Moving Average Convergence Divergence Indikator
Zeigt Trendrichtung und -stärke durch die Differenz zweier gleitender Durchschnitte
Der MACD berechnet die Differenz zwischen einem schnellen (5-Perioden) und einem langsamen (13-Perioden) exponentiellen gleitenden Durchschnitt. Ist der MACD positiv, liegt der schnelle Durchschnitt über dem langsamen — der Trend ist aufwärts.
MACD = EMA(close, 5) - EMA(close, 13)
Positiver MACD: Kurzfristiger Trend ist stärker als langfristiger → Aufwärtsdynamik.
Negativer MACD: Kurzfristiger Trend schwächer → Abwärtsdynamik.
Volume Ratio Indikator
Vergleicht das aktuelle Handelsvolumen mit dem Durchschnitt
Die Volume Ratio zeigt, ob gerade überdurchschnittlich viel oder wenig gehandelt wird. Ein Wert von 2.0 bedeutet doppelt so viel Volumen wie im Tagesdurchschnitt — das deutet oft auf wichtige Nachrichten oder starke Marktbewegungen hin.
Volume Ratio = Aktuelles Volumen / SMA(Volumen, 34 Bars)
Begrenzt auf 0-5, Normalwert bei ~1.0. Hohe Werte verstärken die Aussagekraft anderer Signale.
Volatilität Indikator
Misst die Schwankungsbreite der Renditen
Die Volatilität ist die Standardabweichung der Bar-Renditen über einen Handelstag (34 Bars bei 15-Min-Kerzen). Hohe Volatilität bedeutet große Kursschwankungen — mehr Chance, aber auch mehr Risiko.
Volatilität = StdDev(returns_1bar, 34 Bars)
Im Observation Space begrenzt auf max. 0.5. Die Volatilität beeinflusst auch die Position-Sizing: Bei hoher Volatilität werden kleinere Positionen eröffnet.
ATR — Average True Range Risiko
Misst die durchschnittliche Schwankungsbreite pro Bar (inkl. Gaps)
Die ATR berechnet die durchschnittliche „wahre Spanne“ über 14 Perioden. Im Unterschied zur einfachen High-Low-Spanne berücksichtigt die True Range auch Kurslücken (Gaps) zum Vortagesschluss.
True Range = max(High - Low, |High - Close_prev|, |Low - Close_prev|)
ATR = SMA(True Range, 14)
Die ATR wird für die Berechnung von Stop-Loss Levels verwendet: Stop-Loss = Entry - max(ATR × 1.5, Entry × 2%).
DAX — Deutscher Aktienindex Markt
Leitindex der 40 größten börsennotierten Unternehmen Deutschlands
Der DAX (^GDAXI) bildet die Wertentwicklung der 40 größten deutschen Aktiengesellschaften ab. Er dient als Barometer für den gesamten deutschen Aktienmarkt. Wenn der DAX fällt, fallen typischerweise auch die meisten Einzelaktien — unabhängig von deren individueller Qualität.
Unser System nutzt den DAX als Markt-Referenz: Die DAX-Tagesrendite und die Korrelation jeder Aktie mit dem DAX fließen als Features in den Trading Agent ein.
DAX-Rendite Markt
Tagesperformance des DAX-Index — zeigt die allgemeine Marktstimmung
Die DAX-Tagesrendite misst, wie sich der Gesamtmarkt an diesem Tag entwickelt hat. Eine positive Rendite bedeutet steigende Märkte, eine negative fallende.
DAX-Rendite = (DAX_close_jetzt - DAX_close_vor_34_Bars) / DAX_close_vor_34_Bars
Dieses Feature hilft dem Agent zu erkennen, ob eine Aktie gegen den Markt läuft oder mit ihm. Wenn der DAX stark fällt aber eine Aktie stabil bleibt, ist das ein Stärke-Signal.
DAX-Korrelation Markt
Wie stark bewegt sich eine Aktie im Gleichschritt mit dem Gesamtmarkt?
Die DAX-Korrelation ist ein rollierender Korrelationskoeffizient (-1 bis +1) zwischen den Bar-Renditen einer Aktie und denen des DAX-Index, berechnet über 5 Handelstage (170 Bars).
DAX-Korrelation = corr(returns_aktie, returns_dax, Fenster=170 Bars)
- +1.0: Aktie bewegt sich exakt mit dem DAX (hohe Abhängigkeit)
- 0.0: Keine Beziehung zum Markt (unabhängig)
- -1.0: Aktie bewegt sich entgegengesetzt zum DAX
Beispiel: Rheinmetall hat oft niedrige DAX-Korrelation, da Rüstungsaktien eigenen Zyklen folgen. SAP hingegen hat typisch hohe Korrelation als DAX-Schwergewicht.
XETRA Markt
Elektronisches Handelssystem der Deutschen Börse
XETRA (Exchange Electronic Trading) ist die wichtigste Handelsplattform für deutsche Aktien. Die Handelszeiten sind 9:00-17:30 CET (= 7:00-15:30 UTC im Sommer). Ein Handelstag hat bei 15-Minuten-Kerzen genau 34 Bars (8,5 Stunden × 4 Bars/Stunde).
Unser Paper Trading läuft nur während der XETRA-Handelszeiten (alle 5 Minuten, Mo-Fr).
Sentiment-Score Feature
FinBERT-basierte Stimmungsbewertung von Finanznachrichten (0.1 bis 0.9)
Der Sentiment-Score wird aus der FinBERT-Klassifikation berechnet. Das Modell gibt für jeden Nachrichtenartikel eine Wahrscheinlichkeit für „positiv“, „negativ“ und „neutral“ aus. Daraus wird ein gerichteter Score berechnet:
Positiv: Score = 0.5 + Konfidenz × 0.5 → Bereich 0.5 - 1.0
Negativ: Score = 0.5 - Konfidenz × 0.5 → Bereich 0.0 - 0.5
Neutral: Score = 0.5
„SAP steigert Umsatz über Erwartungen“ → label=positiv, conf=0.93 → Score = 0.965
„Bayer verliert Glyphosat-Klage“ → label=negativ, conf=0.87 → Score = 0.065
Die Scores werden stündlich aus dem DynamoDB-Cache aggregiert und auf die 15-Min-Kerzen forward-filled. Werte im Bereich 0.45-0.55 gelten als neutral zone — in dieser Zone werden keine neuen Positionen eröffnet.
Sentiment-Trend Feature
Veränderung des Sentiment-Scores über 4 Stunden
Der Sentiment-Trend misst, ob sich die Nachrichtenstimmung verbessert oder verschlechtert. Er wird als Differenz des Sentiment-Scores über 4 Bars (= 1 Stunde bei 15-Min-Kerzen) berechnet.
Sentiment-Trend = Sentiment_Score(t) - Sentiment_Score(t - 4 Bars)
- Positiv (z.B. +0.1): Stimmung wird besser — unterstützt Kaufsignale
- Negativ (z.B. -0.1): Stimmung verschlechtert sich — Vorsicht
- ~0: Stabile Stimmung
Begrenzt auf den Bereich -0.5 bis +0.5. Der Trend ist besonders wertvoll, weil er Veränderungen erkennt, nicht nur den absoluten Wert.
Observation Space — 16 Features ML
Alle Informationen, die der Trading Agent bei jeder Entscheidung sieht
Der Observation Space definiert, welche Daten der PPO-Agent als Eingabe erhält. Jeder „Zustand“ ist ein Vektor mit 16 Zahlen — das ist alles, was der Agent über die aktuelle Marktsituation weiß:
| # |
Feature |
Bereich |
Beschreibung |
| 1 | Kurs | close/100 | Normalisierter Schlusskurs |
| 2 | Sentiment-Score | 0.1-0.9 | FinBERT Stimmungsbewertung |
| 3 | Sentiment-Trend | -0.5 bis 0.5 | 4h-Veränderung des Sentiments |
| 4 | Volumen | vol/1M | Normalisiertes Handelsvolumen |
| 5 | Volume Ratio | 0-5 | Volumen vs. Tagesdurchschnitt |
| 6 | Returns 1h | unbegrenzt | Stundenrendite |
| 7 | Returns 1d | unbegrenzt | Tagesrendite |
| 8 | Volatilität | 0-0.5 | Schwankungsbreite (34 Bars) |
| 9 | RSI | 0-1 | Relative Strength Index / 100 |
| 10 | MACD | unbegrenzt | Trenddifferenz (5/13 EMA) |
| 11 | Bollinger Position | 0-1 | Position innerhalb der Bands |
| 12 | DAX-Rendite | unbegrenzt | Tagesperformance des DAX-Index |
| 13 | DAX-Korrelation | -1 bis 1 | Gleichlauf mit dem Gesamtmarkt |
| 14 | Cash-Anteil | 0-1+ | Verfügbares Cash / Startkapital |
| 15 | Positionsgröße | 0-1 | Gehaltene Aktien / 100 |
| 16 | Episode-Fortschritt | 0-1 | Aktueller Schritt / Gesamtschritte |
Action Space — 5 Aktionen ML
Die möglichen Handelsentscheidungen des Agents
Der Agent wählt bei jedem Schritt eine von 5 Aktionen. Partielle Käufe und Verkäufe ermöglichen feinere Positionssteuerung als ein einfaches Alles-oder-Nichts:
| Aktion |
Name |
Effekt |
| 0 | HOLD | Keine Aktion — Position unverändert |
| 1 | BUY_SMALL | 25% des verfügbaren Cash investieren |
| 2 | BUY_FULL | 100% des verfügbaren Cash investieren |
| 3 | SELL_HALF | 50% der gehaltenen Position verkaufen |
| 4 | SELL_ALL | Gesamte Position liquidieren |
Vorteil gegenüber 3 Aktionen (alt: BUY/SELL/HOLD): Der Agent kann vorsichtig einsteigen (BUY_SMALL) und bei Bestätigung nachlegen (BUY_FULL), oder Teilgewinne mitnehmen (SELL_HALF) ohne die gesamte Position aufzugeben.
Reward Function — Sharpe-basiert ML
Die Belohnungsfunktion, die den Agent zum profitablen Handeln motiviert
Die Reward Function definiert, was „gutes Handeln“ bedeutet. Unser Agent wird nicht nur für Gewinne belohnt, sondern auch für risiko-adjustierte Gewinne (Sharpe-ähnlich):
reward = portfolio_return × 0.5 + rolling_sharpe × 0.3 + step_return × 0.2 + sentiment_bonus
- Portfolio Return (50%): Gesamtrendite seit Start — belohnt langfristiges Wachstum
- Rolling Sharpe (30%): Rendite/Risiko-Verhältnis über 40 Schritte — bestraft hohe Schwankungen
- Step Return (20%): Rendite des aktuellen Schritts — sofortiges Feedback
- Sentiment Bonus: +0.01 wenn Aktion zum Sentiment passt (Kauf bei positivem Sentiment), -0.01 bei Widerspruch
Warum nicht einfach nur Rendite? Ein Agent, der nur auf Rendite optimiert, wird extreme Risiken eingehen. Die Sharpe-Komponente bestraft wilde Schwankungen und fördert gleichmäßige, stabile Gewinne.
Walk-Forward Validation ML
Robuste Modellvalidierung mit rollierenden Zeitfenstern
Im Gegensatz zu einem einfachen Train/Test-Split (z.B. 70/30) verwendet Walk-Forward Validation mehrere aufeinanderfolgende Zeitfenster. Das Modell wird auf älteren Daten trainiert und auf neueren getestet — genau wie in der Realität, wo man nie zukünftige Daten sehen kann.
Fold 1: Train [0 ... 60%] → Test [60% ... 73%]
Fold 2: Train [0 ... 73%] → Test [73% ... 87%]
Fold 3: Train [0 ... 87%] → Test [87% ... 100%]
Bestes Modell = Fold mit höchster Test-Rendite
- 3 Folds: Drei verschiedene Marktphasen werden getestet
- Schutz vor Overfitting: Ein Modell, das nur auf einem Zeitraum gut funktioniert, wird erkannt
- Bestes Modell wird gespeichert: Nur der Fold mit der besten Test-Rendite wird deployed
Warum nicht einfach 70/30? Ein einfacher Split testet nur einen Marktzustand. Walk-Forward zeigt, ob das Modell in verschiedenen Marktphasen (Aufwärtstrend, Seitwärts, Korrektur) funktioniert.
Gamma — Discount Factor ML
Wie stark gewichtet der Agent zukünftige Belohnungen gegenüber sofortigen?
Gamma (γ) bestimmt, wie weit der Agent in die Zukunft „denkt“. Ein Gamma von 0.97 bedeutet: Eine Belohnung in 10 Schritten ist 0.9710 = 74% so viel wert wie eine sofortige Belohnung.
Diskontierter Wert = reward × γt
γ = 0.97: nach 10 Schritten → 74% Wert, nach 50 Schritten → 22% Wert
γ = 0.99: nach 10 Schritten → 90% Wert, nach 50 Schritten → 61% Wert
- γ = 0.97 (unser Wert): Kürzerer Horizont — der Agent fokussiert auf Gewinne der nächsten ~30 Schritte
- γ = 0.99 (alter Wert): Langer Horizont — kann zu „ewigem Warten“ auf zukünftige Gewinne führen
Warum 0.97 statt 0.99? Bei 15-Minuten-Kerzen und volatilem Aktienmarkt ist ein kürzerer Horizont realistischer. Der Agent soll auf aktuelle Marktbedingungen reagieren, nicht auf hypothetische Gewinne in 3 Tagen.
PPO — Proximal Policy Optimization ML
Der Reinforcement-Learning-Algorithmus, der unseren Trading Agent trainiert
PPO (Schulman et al., 2017 — OpenAI) ist ein Policy-Gradient-Algorithmus, der die Handelsstrategie direkt optimiert. Er wurde auch für das Training von ChatGPT (RLHF) eingesetzt. Zwei Kernideen machen PPO besonders stabil:
- Clipping (Clip Range = 0.2): Die Policy darf sich pro Update maximal um ±20% ändern. Das verhindert, dass ein einzelner schlechter Batch das gesamte Modell ruiniert.
- Multiple Epochs (= 10): Jede gesammelte Erfahrung wird 10-mal für Updates genutzt, statt sie nach einmal Lernen wegzuwerfen. Das macht PPO deutlich effizienter als ältere Methoden.
Unser System trainiert 40 unabhängige PPO-Modelle (eines pro DAX-Aktie) parallel via AWS Step Functions. Jedes Modell lernt die optimale Handelsstrategie für seine spezifische Aktie.
Stop-Loss / Take-Profit Risiko
Automatische Verlustbegrenzung und Gewinnmitnahme
Jede eröffnete Position bekommt automatisch ein Stop-Loss (SL) und Take-Profit (TP) Level:
- Stop-Loss: Mindestens 2% unter dem Einstieg oder 1.5× ATR — je nachdem was größer ist
- Take-Profit: 2:1 Reward/Risk Ratio — der potenzielle Gewinn ist doppelt so hoch wie das Risiko
- Trailing Stop: Bei >5% Gewinn wird der Stop auf 50% des unrealisierten Gewinns nachgezogen
Beispiel: Kauf bei 100€, ATR = 2€
SL = 100 - max(3, 2) = 97€ — TP = 100 + (100 - 97) × 2 = 106€
Maximaler Verlust: 3€ (3%), Maximaler Gewinn: 6€ (6%)
Sharpe Ratio Risiko
Maß für die risiko-adjustierte Rendite
Die Sharpe Ratio setzt die Rendite ins Verhältnis zum eingegangenen Risiko (Volatilität). Ein Wert von 1.0 bedeutet: Für jede Einheit Risiko wird eine Einheit Rendite erzielt. Höher ist besser.
Sharpe Ratio = Durchschnittliche Rendite / Standardabweichung der Renditen
- < 0: Verluste
- 0 - 0.5: Schwache risiko-adjustierte Performance
- 0.5 - 1.0: Akzeptabel
- > 1.0: Gut — Rendite überwiegt das Risiko deutlich
In unserer Reward Function fließt eine Rolling Sharpe Ratio (40-Schritt-Fenster) mit 30% Gewicht ein. Das motiviert den Agent, gleichmäßig profitable Trades zu machen, statt alles auf eine riskante Wette zu setzen.
Drawdown Risiko
Maximaler Verlust vom Höchststand — das wichtigste Risikomaß
Der Drawdown misst den prozentualen Rückgang vom bisherigen Portfolio-Höchstwert. Er zeigt, wie viel ein Investor im schlimmsten Fall hätte verlieren können.
Drawdown = (Startkapital - Aktueller Portfoliowert) / Startkapital
- < 5%: Risiko-Level LOW
- 5% - 10%: Risiko-Level MEDIUM
- > 10%: Risiko-Level HIGH
- ≥ 20%: EMERGENCY STOP — alle Positionen werden sofort geschlossen
Beispiel: Startkapital 100.000€, aktueller Wert 88.000€
Drawdown = (100.000 - 88.000) / 100.000 = 12% → Risiko HIGH