From 6f039d0b43724d89ac149cae030f20b0ab545016 Mon Sep 17 00:00:00 2001 From: nexo312 Date: Thu, 20 Aug 2026 10:06:24 +0000 Subject: [PATCH] Modul-11: Analytics FREIGEGEBEN (deterministische Kennzahlen aus Trade-Journal, Portfolio/Strategie/Regime/Period) --- modul-11-analytics.md | 82 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 modul-11-analytics.md diff --git a/modul-11-analytics.md b/modul-11-analytics.md new file mode 100644 index 0000000..e6e347f --- /dev/null +++ b/modul-11-analytics.md @@ -0,0 +1,82 @@ +# Modul-11: Analytics + +**Status: FREIGEGEBEN** · Container `Modul-11-Analytics` · Image `analytics-service:0.1.0` + +## Zweck +Auswertung der Trade-Journal-Daten aus **Modul-10** (`trade_journal`) zu reproduzierbaren Performance-Kennzahlen. Deterministische Berechnung — gleiche Datenbasis → gleiche Ergebnisse. **V1 ohne KI/ML, ohne Orders, ohne automatische Strategieänderungen.** + +## Architektur / Datenfluss + +``` +TRADE_RECORDED (market.journal / trade.recorded) + │ + ▼ +Modul-11-Analytics ── konsumiert über Queue `analytics.input` + │ + ├── liest read-only → trade_journal (Modul-10, PostgreSQL) + ├── schreibt → analytics_snapshot, strategy_performance, daily_performance + └── publiziert (opt.)→ ANALYTICS_UPDATED (market.analytics / analytics.updated) + +API (Docker-intern, Port 55011): + /health, /health/ready + /analytics/portfolio Gesamt-/Portfolio-Performance + /analytics/strategy je Strategie+Version + /analytics/regime je Market Regime + /analytics/period je Monat (ab optionalem from_date) + /analytics/rebuild (POST) deterministischer Rebuild aus DB +``` + +Primärquelle ist `TRADE_RECORDED`; zusätzlich liest Analytics direkt aus PostgreSQL (`trade_journal`), da für reproduzierbare Auswertungen ein vollständiger, deterministischer Rebuild aus der DB sinnvoller ist. `TRADE_RECORDED`-Events triggern eine Neuberechnung (Idempotenz: identisches Event → keine Doppelzählung). + +## Datenquelle & Realisationslogik +- **Nur `status = 'CLOSED'` UND `realized_pnl IS NOT NULL`** fließen in realisierte Performance ein. +- **Offene Trades** (`OPEN`) werden separat ausgewiesen (`open_trade_count`) und zählen NICHT als realisierte Trades. +- Gruppierungsfelder aus `trade_journal`: `strategy`, `strategy_version`, `symbol`, `asset_class`, `direction` (LONG/SHORT), `regime`, `signal_score`. +- Zeitraum-Gruppierung nach `exit_time` (realisierter Trades), optional ab `from_date`. +- **Keine Lookahead-/Survivorship-Tricks**: nur tatsächlich geschlossene Trades, deterministische Equity-Kurve. + +## Kennzahlen (V1) +- Anzahl Trades (realisiert + offen getrennt) +- Winrate / Lossrate +- durchschnittlicher Gewinn / Verlust +- durchschnittliches R (realized_r_multiple) +- Expectancy (Währung + R) +- Profit Factor (gross_profit / gross_loss) +- Netto-PnL +- Brutto-Gewinn / Brutto-Verlust +- Max Drawdown (aus Equity-Kurve der realisierten PnL) +- Durchschnittliche Haltedauer (entry_time→exit_time, Stunden) +- Bester / schlechtester Trade + +## Eigene Tabellen (Migration `migrations/001_analytics.sql`) +- `analytics_snapshot` — stabiler Snapshot der Gesamt-Performance (jeder Rebuild = neue Zeile, chronologisch append). +- `strategy_performance` — Kennzahlen je Strategie+Version. +- `daily_performance` — Tageskennzahlen (Backtesting/Reporting). + +Diese fassen KEINE bestehenden Tabellen an (read-only auf `trade_journal`). + +## RabbitMQ +- **Queue** `analytics.input` (durable, topic `market.journal`, Routing `trade.recorded`), manuelles ACK, Reconnect mit Backoff (1→2→4→8→16s), kein Zombie. +- **Publiziert** optional `ANALYTICS_UPDATED` (topic `market.analytics`, Routing `analytics.updated`) — frische Verbindung je Publish (Bug-Fix-Pattern aus Modul-10), `conn.close()` nach jedem Publish. + +## Verifikation (20.08.2026) +| Test | Ergebnis | +|---|---| +| 1–7 Pure Metriken (Gewinn/Verlust, Winrate, PF, Expectancy, Max DD, Gruppierung, offene≠realisierte) | **OK** | +| 8 Idempotenz (identisches Event → keine Doppelzählung) | **OK** | +| 9 Rebuild aus DB → identische Kennzahlen | **OK** | +| 10 RabbitMQ-Reconnect (Backoff 4→8→16s, erneuter Connect, 1 Consumer) | **OK** | +| E2E 03→11 (Seed realisierter Trades, Portfolio/Strategie/Regime, DB + Idempotenz) | **OK** | + +- Health/Ready: `200` Port 55011 (PostgreSQL ✓, RabbitMQ ✓, Consumer ready ✓). +- Endzustand nach Freigabe: 2 echte OPEN-Trades im Journal, 0 realisierte → Snapshot zeigt 0/2. + +## Betriebshinweise +- Kein öffentlicher Port (nur `expose: 55011`). +- `restart: unless-stopped`. +- Compose-Pfad VPS: `/opt/trading-modules/docker-compose.yml`. +- Forgejo-Doku: `nexo312/trading-system-docs`, Commit-ID siehe unten. + +--- +*Geändert von: Rain Ocampo (Hermes)* +*Datum: 20.08.2026* — Modul-11-Analytics, Status FREIGABEGEBEN.