📈 Trading Journal – Overview
Ziel
Der Trading-Journal-Service dient der strukturierten Erfassung, Analyse und Nachverfolgung von Trades.
Der Service unterstützt dabei, Handelsentscheidungen, Markteinschätzungen und Ergebnisse nachvollziehbar zu dokumentieren.
Kernfunktionen
- Trades erfassen
- Trade-Historie anzeigen
- Trading-Setups dokumentieren
- Gewinne und Verluste auswerten
- Kommentare und Learnings festhalten
- Status-Lifecycle eines Trades verwalten (
offen→geschlossen, alternativverworfen) - Orders aus dem Trade Optimizer direkt als aktiven Trade (status=
offen) entgegennehmen - Trade schließen inkl. automatischem Kursabruf vom Trading Data Layer, Vorschau und Erfolgsauswertung (Pips, Rendite-%) (TJ-009)
- KPI-Snapshot der Trend-/Fundamentalanalyse zum Übernahmezeitpunkt speichern, als Grundlage für spätere Performance-Analyse
- Einzelne Trades endgültig aus der Datenbank löschen (TJ-010)
- KPI-Performance über alle geschlossenen Trades auswerten: Vorhersage (Analyse-Kategorie) vs. tatsächliches Ergebnis (TJ-011)
- Renditeziel-, These-Invalidierungs- und Gewinnsicherungs-Alerts pro Trade konfigurierbar, per Scheduler überwacht (TJ-012/TJ-013)
- Live-Tacho-Anzeigen für Rendite, Trend-Ausrichtung und Gewinnsicherung im aufgeklappten Trade-Bereich (TJ-014)
Plattform-Integration
Der Service nutzt Plattform-Funktionen für:
- Authentifizierung
- Rollenmodell
- Usermanagement
- Routing
Zusätzlich wird der Service vom Trade Optimizer aufgerufen, um Orders
direkt als aktiven Trade (status=offen) anzulegen (REQ-TO-009). Umgekehrt
ruft das Trading Journal selbst einen weiteren Service auf:
- Trading Data Layer – zum Abruf des aktuellen Kurses beim Schließen
eines Trades (TJ-009,
GET /data-layer/forex/latest, TRADINGDL-008) - Signal Analytics Service – für die KPI-Performance-Aggregation
(TJ-011 delegiert die Gruppierungs-/Berechnungslogik an
SA-003, statt sie lokal zu pflegen)
Zielbild
Ein authentifizierter Benutzer kann:
- Trades dokumentieren
- vergangene Trades analysieren
- Trading-Muster erkennen
- Performance nachvollziehen
- vom Trade Optimizer übernommene Orders als aktive Trades im Journal verwalten
Architektur
Datenmodell
Hinweis: Es existiert bislang keine separate
data-model.md. Das folgende Modell ist ein Best Guess auf Basis der vorhandenenTJ-*.yaml-Requirements und muss während der Implementierung verifiziert bzw. angepasst werden.
Entität: Trade
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| id | UUID | ja | Primärschlüssel |
| user_id | UUID | ja | Zuordnung zum Benutzer (TJ-001, TJ-006) |
| symbol | string | ja | Handelsinstrument, z.B. "EUR/USD" |
| direction | enum [long, short] | ja | Handelsrichtung |
| entry_price | float | ja | Einstiegspreis |
| stop_loss | float | ja | Stop-Loss-Preis |
| take_profit | float | ja | Take-Profit-Preis |
| lot_size | float | nein | Positionsgröße; bei Übernahme aus Trade Optimizer aktuell fix 0.01 |
| status | enum [offen, geschlossen, verworfen] | ja | Siehe Status-Lifecycle unten |
| source | enum [manuell, trade-optimizer] | ja | Herkunft des Eintrags |
| result | enum [win, loss, breakeven] | nein | Nur gesetzt wenn status = geschlossen |
| pnl | float | nein | Gewinn/Verlust (absolut); nur gesetzt wenn status = geschlossen |
| pnl_percent | float | nein | Rendite in %, relativ zum Entry-Preis (TJ-009); nur gesetzt wenn status = geschlossen |
| pips | float | nein | Kursbewegung in Pips zwischen Entry und Exit (TJ-009); nur gesetzt wenn status = geschlossen |
| exit_price | float | nein | Schlusskurs; nur gesetzt wenn status = geschlossen (TJ-009) |
| comment | string | nein | Kurzer Kommentar zur Order, optional aus dem Trade Optimizer übernommen (REQ-TO-009) |
| analysis_snapshot | JSON | nein | Snapshot der Trend-/Fundamentalanalyse-KPIs zum Zeitpunkt der Übernahme (REQ-TO-009); strukturiert gespeichert, siehe Unterfelder unten |
| alert_renditeziel_active | bool | ja | Default false. Renditeziel-Alert aktuell aktiv (TJ-012) |
| alert_these_invalidierung_active | bool | ja | Default false. These-Invalidierungs-Alert aktuell aktiv (1h-Trend, unabhängig vom Ergebnis, TJ-012 v2.0) |
| alert_gewinnsicherung_active | bool | ja | Default false. Gewinnsicherungs-Alert (Trailing) aktuell aktiv, kann bei neuem Peak automatisch reaktivieren (TJ-012 v2.0) |
| alert_renditeziel_sent_at | datetime, nullable | nein | Zeitpunkt des letzten Auslösens (TJ-012/TJ-013) |
| alert_these_invalidierung_sent_at | datetime, nullable | nein | Zeitpunkt des letzten Auslösens (TJ-012/TJ-013) |
| alert_gewinnsicherung_sent_at | datetime, nullable | nein | Zeitpunkt des letzten Auslösens/letzten Peaks (TJ-012/TJ-013) |
| these_invalidierung_pending_since | datetime, nullable | nein | Zeitpunkt des ersten unbestätigten Zonen-Austritts, für die Zwei-Zyklen-Bestätigung (TJ-012/TJ-013 v2.0) |
| peak_pnl_percent | float, nullable | nein | Höchster live_pnl_percent seit Erreichen des Renditeziels, für Gewinnsicherung (TJ-012/TJ-013 v2.0) |
| trade_date | date | ja | Datum des Trades (TJ-001) |
| created_at | datetime | ja | Anlagezeitpunkt |
| updated_at | datetime | ja | Letzte Änderung |
analysis_snapshot-Struktur (aus REQ-TO-009):
| Feld | Typ | Beschreibung |
|---|---|---|
| trend_score | float | Technischer Score zum Übernahmezeitpunkt |
| trend_category | string | z.B. "Bullish" |
| trend_indicators | JSON-Liste | EMA/RSI/MACD/Supertrend/BB-Aussagen |
| fundamental_score | float | Fundamentaler Score zum Übernahmezeitpunkt |
| fundamental_category | enum [stark_bullish, bullish, neutral, bearish, stark_bearish] | Seit REQ-TO-001 v1.2 fester Enum (vorher Freitext) |
| fundamental_drivers | JSON-Liste von { indicator, category, detail } |
Je Treiber eigene Kategorie aus demselben Enum (seit REQ-TO-001 v1.2, vorher reine Strings) |
Als eigene Tabelle statt reinem JSON-Blob speichern, falls ihr später gezielt nach einzelnen KPI-Werten filtern/aggregieren wollt (z.B. "wie oft lag trend_score > 40 bei tatsächlichem Gewinn") – JSON reicht, wenn die Auswertung erstmal nur pro Trade und nicht KPI-übergreifend erfolgt.
Entität: TradeNote
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
| id | UUID | ja | Primärschlüssel |
| trade_id | UUID | ja | Zugehöriger Trade |
| text | string | ja | Notiz-/Learning-Text (TJ-007) |
| created_at | datetime | ja | Anlagezeitpunkt |
| updated_at | datetime | ja | Letzte Änderung |
Status-Lifecycle
offen: Trade ist aktuell eine laufende Position in MetaTrader5. Alle neuen Trades starten mit diesem Status, unabhängig von der Quelle.geschlossen: Trade ist abgeschlossen,resultundpnlsind gesetzt.verworfen: Trade wurde manuell als nicht mehr relevant markiert (z.B. Setup verworfen, Fehleintrag). Bleibt in der Historie sichtbar (keine Löschung). Wechsel nur ausoffenmöglich (TJ-002).
Validierungsregeln
symbol,direction,entry_price,stop_loss,take_profit,trade_datesind Pflichtfelder (TJ-001)resultundpnldürfen nur gesetzt sein, wennstatus = geschlossen- Ein Statuswechsel zu
verworfenist nur ausoffenheraus erlaubt (TJ-002)
Offene Fragen
- [ ] Soll
lot_sizebei manuell erfassten Trades (TJ-001, ohne Trade-Optimizer-Herkunft) verpflichtend sein? - [ ] Werden Statuswechsel historisiert (Audit-Trail), oder wird nur der aktuelle Status gespeichert?
- [ ] TJ-008: Ist es korrekt, dass bei Orderübernahme nach 17:30 Uhr kein Reminder für denselben Tag angelegt wird (statt z.B. auf den nächsten Handelstag zu verschieben)? Aktuell nur eine Annahme, nicht bestätigt.
- [ ] TJ-009: Ist
pnl_percentals reine Kursbewegung relativ zum Entry korrekt, oder soll eine Konto-/Margin-Bezugsgröße einfließen (die aktuell nirgends im Journal hinterlegt ist)? - [ ] TJ-010: Braucht das endgültige Löschen eine Bestätigungs-Abfrage in der UI? Ist Löschen für jeden Status erlaubt, auch für
offen? - [x] ~~TJ-011: fundamental_category vereinheitlichen~~ – gelöst durch REQ-TO-001 v1.2 (fester 5-stufiger Enum, gleiche Schwellenwerte wie trend_category). Voraussetzung bleibt, dass der Fundamental Analysis Service selbst normalisierte Einzel-Indikator-Scores liefert – das ist außerhalb dieser Doku und muss dort separat umgesetzt werden.
API-Kontrakt
Hinweis: Es existiert bislang keine separate
api-contract.md. Der Pfad-Präfix/tradingist gegenplatform/architecture/overview.mdverifiziert (Routertrading→/trading, dort seit 2026-07-16 korrigiert; vorher fälschlich als/api/v1/journalgeraten). Die konkreten Endpunkte darunter sind weiterhin ein Best Guess auf Basis der vorhandenenTJ-*.yaml-Requirements und müssen während der Implementierung final verifiziert werden.
Authentifizierung
JWT Bearer Token im Authorization-Header, erforderlich für alle Endpunkte (TJ-006).
Endpunkte
| Methode | Pfad | Beschreibung | Requirement |
|---|---|---|---|
| POST | /trading/trades | Neuen Trade anlegen (aktuell nur genutzt via Trade Optimizer) | TJ-001 |
| GET | /trading/trades | Trade-Liste/Historie, optional gefiltert nach status |
TJ-003 |
| GET | /trading/trades/{id} | Trade-Details inkl. Notizen | TJ-004 |
| PATCH | /trading/trades/{id} | Trade aktualisieren, inkl. Statuswechsel zu verworfen |
TJ-002 |
| GET | /trading/trades/{id}/close-preview | Vorschau: exit_price, pips, result, pnl, pnl_percent – ohne zu persistieren | TJ-009 |
| POST | /trading/trades/{id}/close | Trade endgültig schließen (persistiert die Vorschau-Werte oder einen manuellen exit_price) | TJ-009 |
| DELETE | /trading/trades/{id} | Trade endgültig löschen (Hard-Delete, inkl. Notizen) | TJ-010 |
| GET | /trading/stats | Trading-Statistiken | TJ-005 |
| GET | /trading/kpi-performance | KPI-Performance: Vorhersage (Analyse-Kategorie) vs. Realität, aggregiert über geschlossene Trades | TJ-011 |
| GET | /trading/trades/{id}/live-status | Live-Werte für die Tacho-Anzeigen (Rendite, Trend-Ausrichtung, Gewinnsicherung) | TJ-014 |
| POST | /trading/trades/{id}/notes | Notiz zu einem Trade hinzufügen | TJ-007 |
| PATCH | /trading/trades/{id}/notes/{note_id} | Notiz bearbeiten | TJ-007 |
Response GET /trading/trades/{id}/close-preview:
Request-Body POST /trading/trades/{id}/close:
exit_price ist optional; fehlt es, ruft das Journal automatisch GET /data-layer/forex/latest?pair={symbol} ab (TRADINGDL-008) – dieselbe Quelle wie beim Preview-Aufruf.
Response 200:
{ "id": "…", "status": "geschlossen", "exit_price": 1.0920, "pips": 70, "result": "win", "pnl": 70.0, "pnl_percent": 0.65 }
Request-Body POST /trading/trades:
{
"symbol": "EUR/USD",
"direction": "long",
"entry_price": 1.0850,
"stop_loss": 1.0810,
"take_profit": 1.0950,
"lot_size": 0.01,
"trade_date": "2026-07-08",
"source": "trade-optimizer",
"comment": "Bullish Engulfing an Support, MTF-Ausrichtung bestätigt",
"analysis_snapshot": {
"trend_score": 45,
"trend_category": "Bullish",
"trend_indicators": ["EMA: Aufwärtstrend", "RSI: Neutral (52)", "MACD: Bullish Cross"],
"fundamental_score": 30,
"fundamental_category": "bullish",
"fundamental_drivers": [
{ "indicator": "Fed Funds Rate", "category": "bullish", "detail": "Zinspause erwartet" },
{ "indicator": "CPI", "category": "stark_bullish", "detail": "rückläufig" }
]
}
}
source, comment und analysis_snapshot sind optional im Request; wird source nicht mitgeschickt, gilt source: manuell. Alle neuen Trades erhalten immer status: offen (serverseitig gesetzt, nicht vom Client steuerbar).
Response 201:
Request-Body PATCH /trading/trades/{id} (Statuswechsel zu verworfen):
DELETE /trading/trades/{id}: Kein Body. Response 204 bei Erfolg, 404 falls der Trade nicht existiert. Löscht den Trade und zugehörige Notizen unwiderruflich (siehe TJ-010).
Fehlercodes:
| Code | Bedeutung |
|---|---|
| 400 | Validierungsfehler (z.B. unerlaubter Statuswechsel) |
| 401 | Nicht authentifiziert |
| 404 | Trade nicht gefunden |
Bezug zu REQ-TO-009 / REQ-TO-011
Beide korrekt auf /trading/... verdrahtet (Stand 2026-07-16) – siehe
Changelog. Der ursprüngliche /api/v1/journal/...-Präfix war ein "Best
Guess" aus einer Zeit, in der uns die platform/architecture/overview.md
noch nicht vorlag; dort steht der tatsächliche Router-Präfix
(trading | /trading | Trading Journal: Trade-CRUD, Statistiken).
Fachlicher Fokus
Der Service konzentriert sich auf:
- historische Trades
- Analyse vergangener Entscheidungen
- Verbesserung des eigenen Trading-Verhaltens
Abgrenzung
Nicht Bestandteil des Services:
- automatisiertes Trading
- Market Data Streaming
- Echtzeit-Signalgenerierung
- Broker-Integration
- Automatischer Reminder zu beliebigen anderen Zeitpunkten als 17:30 (nur der End-of-Day-Reminder ist abgedeckt, TJ-008)
- Manuelle Trade-Erfassung über die Journal-UI (Button vorhanden, aktuell ohne Funktion, siehe TJ-001)
- Soft-Delete / Wiederherstellung gelöschter Trades (TJ-010 löscht endgültig, kein Papierkorb)
- Eigene Berechnung von Trend- oder Fundamentalanalyse-Werten. Das Journal konsumiert ausschließlich vorberechnete Kategorien/Scores aus dem Trend Analysis Service (z.B.
GET /api/v1/interpretation, siehe TJ-012/TJ-013) und dem Trading Data Layer – es interpretiert Kerzen, Indikatoren oder Wirtschaftsdaten nicht selbst.
Changelog
| Version | Datum | Änderungen |
|---|---|---|
| 1.10 | 2026-07-27 | TJ-011s Aggregationslogik an den neuen Signal Analytics Service delegiert (SA-003) – neue Plattform-Integration ergänzt |
| 1.9 | 2026-07-16 | TJ-014 neu – Live-Tacho-Anzeigen (Rendite, Trend-Ausrichtung, Gewinnsicherung) im aufgeklappten Trade-Bereich, neuer Endpunkt GET /trading/trades/{id}/live-status |
| 1.8 | 2026-07-16 | Datenmodell an TJ-012 v2.0 angepasst: alert_trendumkehr_active/ alert_trendumkehr_unabhaengig_active umbenannt und neu konzipiert zu alert_these_invalidierung_active (1h, Zonen-Austritt, Zwei-Zyklen- Bestätigung) und alert_gewinnsicherung_active (Preis-Trailing, kein Trend-Bezug mehr). Zwei neue Felder: these_invalidierung_pending_since, peak_pnl_percent. BREAKING CHANGE am Datenmodell gegenüber v1.7. |
| 1.7 | 2026-07-16 | Dritten Trade-Alert-Typ ergänzt (TJ-012 v1.4): Trendumkehr unabhängig vom Renditeziel, feuert auch im Verlust. Zwei weitere Felder im Datenmodell (alert_trendumkehr_unabhaengig_active/_sent_at). |
| 1.6 | 2026-07-16 | Vier neue Alert-Felder im Datenmodell ergänzt (TJ-012, war im Master-Dokument nachzuziehen); Architekturprinzip explizit in der Abgrenzung festgehalten – Journal berechnet keine eigene Trend-/ Fundamentalanalyse, konsumiert nur vorberechnete Werte |
| 1.5 | 2026-07-16 | API-Prefix korrigiert: /trading statt /api/v1/journal (verifiziert gegen platform/architecture/overview.md, Router "trading" → "/trading"). Betrifft alle Endpunkte in diesem Dokument sowie REQ-TO-009, REQ-TO-011, TJ-011. |
| 1.4 | 2026-07-13 | fundamental_category/fundamental_drivers auf festen 5-stufigen Enum umgestellt (analog trend_category, siehe REQ-TO-001 v1.2); offene Frage dazu aufgelöst, verbleibende Abhängigkeit vom Fundamental Analysis Service dokumentiert |
| 1.3 | 2026-07-13 | TJ-004 um KPI-Snapshot-Detailanzeige erweitert; TJ-011 neu – KPI-Performance-Auswertung (Vorhersage vs. Realität), inkl. offener Frage zur Vereinheitlichung von fundamental_category |
| 1.2 | 2026-07-13 | comment und analysis_snapshot im Datenmodell ergänzt (aus REQ-TO-009); manuelle Erfassung über die Journal-UI als deferred markiert (TJ-001); TJ-009 um Vorschau-Endpunkt, Pips und Rendite-% erweitert; TJ-010 neu – endgültiges Löschen von Trades (Hard-Delete) |
| 1.1 | 2026-07-08 | Datenmodell und API-Kontrakt ergänzt (Best Guess, da keine separaten data-model.md/api-contract.md existieren – bei Implementierung ggf. anzupassen); Status-Lifecycle für Trades (vorbereitet/offen/geschlossen/ verworfen) ergänzt zur Integration mit dem Trade Optimizer (Order-Vorbereitung, siehe REQ-TO-009/REQ-TO-011) |
| 1.0 | 2026-06-25 | Initiale Version |