Files
PolyTraderSharp/docs/konzepte/KONZEPT-Modul-Supervisor.md
T

207 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Konzept: Modul „Supervisor" (KI-gestützte Handels-Analyse & Forensik)
> Stand: 2026-07-16
> Ziel: ALLES, was PolyTrader getan (und bewusst NICHT getan) hat, auf einfachem Wege detailliert
> analysierbar machen — Logs, DB-Einträge und das echte Geschehen auf der Plattform — und die Analyse
> durch ein KI-Modell (OpenRouter) durchführen lassen: Warum hat ein Trade funktioniert? Warum nicht?
> Woran lag es?
> **Leitidee: Erst das Datenfundament, dann die KI.** Ein Modell kann nur erklären, was aufgezeichnet
> wurde. Die Analyse ist maximal so gut wie die Rekonstruierbarkeit unserer Entscheidungen.
---
## 0. Datenlage-Audit: Was haben wir, was fehlt?
### Vorhanden ✅
| Quelle | Inhalt | Qualität für Analyse |
|---|---|---|
| `core_trade_log` (TradeRecord) | abgeschlossene Trades aller Module | gut (strukturiert), aber nur das ERGEBNIS |
| Modul-Logs (`mod_copytrading_closed_trades`, `rf_*`) | Modul-Details inkl. Fees, SourceTrader, Cluster | gut |
| Terminal-/Datei-Logs (`/Logs`, Freitext) | Verlauf inkl. `TradeReasoning` (Begründungen) | schlecht maschinenlesbar: Freitext, deutsch, ohne IDs |
| `rf_candidates` | Scanner-Entscheidungen inkl. Reject-Grund | **Vorbild!** genau das Muster, das wir überall brauchen |
| geplant: `acc_ledger` (Accounting-Modul) | unabhängige Plattform-Ground-Truth je Wallet | schließt „echtes Geschehen auf der Plattform" |
### Fehlend ❌ (die eigentlichen Lücken)
1. **Entscheidungsjournal** — der größte Gap. Jede Engine-Entscheidung (BUY/SELL ausgeführt, abgelehnt,
übersprungen) existiert nur als Freitext-Log. Nicht abfragbar („zeig alle MaxBuyPrice-Rejects der
Woche"), nicht mit dem späteren Marktausgang verknüpfbar („was WÄRE aus den Rejects geworden?" —
das ist die halbe Strategie-Kalibrierung!).
2. **Order-Lifecycle nicht persistiert** — Platzierungsversuche, CLOB-Responses, Cancels, Leiter-Stufen
(Preis je Stufe, Wartezeiten, Floor-Erreichung) stehen nur im Log. Für „warum schlechter Fill?"
brauchen wir die Kette als Daten.
3. **Korrelation** — es gibt keine `SignalId`, die Signal → Entscheidung(en) → Order(s) → ClosedTrade
verbindet. Ohne sie ist jedes „Dossier" Handarbeit über Zeitstempel.
4. **Markt-Kontext zum Entscheidungszeitpunkt** — mindestens Signalpreis vs. erzielter Preis vs.
Zeitversatz (Latenz!); mit Phase 1 (Orderbuch) auch Spread/Tiefe. Ohne Kontext kann niemand
beurteilen, ob eine Entscheidung RICHTIG war — nur ob sie gut AUSGING.
5. **Strukturierte Logs** — zusätzlich zum Text ein JSONL-Sink (Timestamp, Level, Source, CorrelationId,
Message, Data), damit Logs filterbar/parsebar sind statt grep-über-Freitext.
---
## 1. Frage 1 — Aufbereitung: das „Trade-Dossier" als zentrale Einheit
**S-0: Datenfundament (Core, nützt sofort auch OHNE KI — z. B. beim Zielland-Debugging):**
- `core_decision_journal`: eine Zeile je Entscheidung. Felder: `SignalId`, Timestamp, Modul, AccountId,
TokenId, Side, Decision (Executed/Rejected/Skipped/Deferred), **ReasonCode (Enum!)** (z. B.
`MaxBuyPriceExceeded`, `PartialSellBelowThreshold`, `ExitPendingSkip`, `SpamBlock`, `BudgetExhausted`,
`BelowPolymarketMinimum`, …), Kontext-Zahlen (SignalPreis, Limitwert, verfügbares Budget, …) als
kompaktes JSON, Freitext wie bisher zusätzlich.
→ Die bestehenden ~20 `TradeReasoning`-Stellen bleiben, schreiben aber ZUSÄTZLICH strukturiert.
- `core_order_events`: Order-Lifecycle (Placed/Rejected/Cancelled/LadderStep/Filled) mit Preisen,
CLOB-Response, `SignalId`.
- `SignalId` (GUID) im `CopySignal`/RF-Flow erzeugen und bis in `ClosedTrade`/`TradeRecord` durchreichen.
- **JSONL-Log-Sink** (TerminalLogger erweitert): eine JSON-Zeile je Event (`ts`, `level`, `source`,
`correlationId`, `message`, optional `data`). JSONL statt JSON-Array: append-fähig, streambar,
zeilenweise filterbar — das KI-freundliche UND effiziente Format. Übergang: zunächst Dual-Sink
(Text + JSONL), Text-Sink später abschaltbar, sobald der Log Viewer etabliert ist.
- **Log Viewer im Terminal-Fenster** (zweiter Tab neben der Live-Anzeige): lädt die JSONL-Dateien und
bereitet sie menschenlesbar auf — Filter nach Datum/Level/Quelle/Text und **CorrelationId
(„zeig mir alles zu diesem Signal")**; Klick auf eine SignalId springt zur kompletten Kette. Damit
ist das effiziente Speicherformat für Menschen genauso zugänglich wie heute der Freitext.
**S-1: Dossier-Generator (pur, testbar):** Für einen Trade / ein abgelehntes Signal alles zusammensetzen:
Signal → Journal-Einträge → Order-Events → Fill/Leiter-Verlauf → ClosedTrade/RF-Position →
`acc_ledger`-Einträge (Plattform-Wahrheit!) → Log-Ausschnitt (Zeitfenster+CorrelationId) → Marktdaten.
Ausgabe als JSON (fürs Modell) und Markdown (für Menschen). Dazu Perioden-Reports über `TradeAnalytics`.
---
## 2. Frage 2 — WIE analysieren: OpenRouter-Agent mit Read-only-Tool-Registry
**v1: Agent IM Prozess (kein separater MCP-Server nötig).** Wir kontrollieren beide Seiten — ein
Function-Calling-Loop gegen OpenRouter (Chat Completions + Tools) ist in C# klein und ohne neue
Abhängigkeit machbar (HttpClient + System.Text.Json). Der Agent bekommt:
1. **System-Kontext:** ein kuratiertes, versioniertes Dokument `docs/analyse/ARCHITEKTUR-KONTEXT.md`
(„So funktioniert PolyTrader": Module, Entscheidungswege, Reason-Codes, Limits, Leiter-Mechanik,
bekannte Eigenheiten). KEIN Code-Dump — destilliertes Verhalten. Wird bei Änderungen am Geld-Pfad
mitgepflegt (Checkliste).
2. **Read-only-Tools** (Registry im Supervisor-Modul):
- `query_trades(filter)` — Core-Trade-Log
- `query_decisions(filter)` — Entscheidungsjournal (inkl. Rejects!)
- `get_dossier(signalId | tokenId+account)` — das komplette Dossier
- `read_logs(zeitraum, level, correlationId, textfilter)` — JSONL-Logs
- `get_ledger(account, zeitraum)` + `get_ledger_diff(...)` — Plattform vs. eigene DB (Accounting)
- `get_kpis(scope)` — TradeAnalytics
- `get_architecture_context()` — das Kontext-Dokument
- **Predictalytics-Tools** (`query_predictalytics_*`): historische Trade-Daten fremder Trader,
Master-Historien, Markt-Statistiken aus unserem Predictalytics-Tool (dessen API wir ohnehin
integrieren). Analytisch besonders wertvoll: **„schlechtes Signal" von „schlechter Ausführung"
trennen** — z. B. Master-Fill vs. unser Fill (Latenzkosten) oder unser Ergebnis vs. das anderer
Trader im selben Markt (Benchmark). Architektur: `IPredictalyticsClient` im **Core** (auch
Trading-Module nutzen ihn später, z. B. Master-Auswahl/AI-Rating); der Supervisor konsumiert ihn
nur read-only. Eigener Egress-Eintrag (unsere eigene API, aber dokumentiert).
**Hart: KEIN Tool kann handeln, canceln oder schreiben.** Der Supervisor ist Beobachter.
**Analyse-Modi:**
- **Einzeltrade-Forensik:** „Erkläre Trade X" → Dossier → Modell begründet mit Daten.
- **Batch-/Muster-Analyse:** „Alle Verlierer der letzten 14 Tage → gemeinsame Faktoren?" (Kategorie?
Uhrzeit? Master? Preisband? Latenz? Leiter-Floor-Fälle?)
- **Counterfactual:** „Was wurde abgelehnt und wie ist der Markt ausgegangen?" (Journal × Resolution).
- **Reconciliation-Anomalien:** DB ↔ Plattform-Differenzen erklären lassen.
- **Täglicher Supervisor-Bericht** (später): Kurzfassung via Threema.
**MCP-Server-Light: ja, aber als Phase S-4.** Dieselbe Tool-Registry zusätzlich über einen lokalen
MCP-Endpoint exponieren → dann können auch externe Clients (Claude Code/Desktop) direkt gegen die
laufende App analysieren. Architektonisch nur ein zweiter Transport über dieselben Tools — deshalb
lohnt es, die Registry von Anfang an transport-agnostisch zu bauen.
---
## 3. Frage 3 — Core- oder Modulebene? Hybrid.
- **Datenfundament = Core.** Journal, Order-Events, SignalId, JSONL sind Core-Contracts (wie der
generische Trade-Log heute); alle Module schreiben hinein (Dual-Write-Muster existiert bereits).
- **Analyse = modulübergreifend.** Profitabilität ist eine Frage über Module/Accounts hinweg — genau
wie das Dashboard.
- **Modul-Spezifisches via Contract:** Core definiert `IAnalysisContextSource` (liefert z. B.
RF-Kandidaten-Kontext oder Copytrading-Master-Kontext zu einem Dossier); Module registrieren
Implementierungen per DI; der Supervisor konsumiert alle. So bleibt „Module kennen einander nicht"
gewahrt (beide Seiten referenzieren nur den Core).
## 4. Frage 4 — Unterbringung: eigenes Modul „Supervisor"
`src/PolyTrader.Modules.Supervisor/` als `IPolyTraderModule` (`Name="Supervisor"`, `DbPrefix="sup_"`),
Registrierung in `Program.cs`, referenziert nur den Core. Eigenes Fenster (Muster RF/Copytrading):
- Tab **Analyse** (Chat mit dem Agenten, Tool-Aufrufe sichtbar/expandierbar — Nachvollziehbarkeit!)
- Tab **Dossier-Browser** (Trade/Signal auswählen → Dossier ansehen, auch ohne KI)
- Tab **Berichte** (gespeicherte Analysen/Tagesberichte, `sup_reports`)
- Tab **Settings** (API-Key, Modellwahl je Aufgabe, Kosten-/Tokenbudget, Bericht-Zeitplan)
Warum Modul statt Core-Fenster: passt ins etablierte Muster (eigene Persistenz `sup_reports`/
`sup_conversations`, eigene Settings, eigener Launcher-Button), hält die KI-Abhängigkeit aus dem Core
heraus und ist einzeln abschaltbar.
## 4a. Supervisor-„Team": Profile statt getrennter Agenten
Die Idee (technischer Supervisor + je Modul ein Strategie-Supervisor) ist richtig — aber als
**Profile über EINER gemeinsamen Infrastruktur**, nicht als getrennte Agenten/Fenster/Prozesse:
| Profil | Fokus | Tools (Subset) | Kontext |
|---|---|---|---|
| **Technik-Supervisor** | Fehler-/Warning-Muster in Logs, Job-Health, API-Ausfälle, Latenzen, Reconciliation-Differenzen — KEINE Strategie-Meinung | read_logs, get_ledger_diff, query_order_events | Architektur-Doku |
| **CopyTrading-Supervisor** | Master-Qualität vs. Ausführungsqualität, Leiter-Verhalten, Reject-Muster | query_decisions, get_dossier, Predictalytics (Master-Historie) | + CopyTrading-Kontextabschnitt |
| **ResolutionFarming-Supervisor** | Kalibrierung (Winrate je Preisband vs. Erwartung), Cluster-Risiken, Scanner-Rejects | query_decisions, rf-Kontext, get_kpis | + RF-Kontextabschnitt |
| *(später)* **Chef-Supervisor** | fasst die Einzelberichte zusammen | die Berichte der anderen | Gesamtsicht |
Ein Profil = System-Prompt + Tool-Subset + Zeitplan + Modellwahl. Gleiche Registry, gleicher Agent-
Runner, gleiche UI (Profil-Auswahl im Analyse-Tab; Berichte je Profil). Modul-Wissen kommt über die
`IAnalysisContextSource`-Registrierung der Module — ein neues Modul bringt seinen Supervisor-Kontext
selbst mit, ohne dass der Supervisor es kennt.
**Bewusst NICHT (v1):** Agent-zu-Agent-Orchestrierung/Diskussionen — teuer, schwer debugbar, wenig
Mehrwert. Profile laufen unabhängig (on-demand oder per Zeitplan); der „Chef" liest nur deren Berichte.
## 5. API-Key: ja, getrennt
**Separater OpenRouter-Key für den Supervisor** (getrennt von künftigen Trading-Modul-Keys wie dem
AI-Markt-Rating):
1. **Kostenzuordnung** — Forensik-Sessions können tokenintensiv werden; sauber getrennt sichtbar.
2. **Spend-Limits je Key** bei OpenRouter → ein Analyse-Amok kann nie das Trading-Budget fressen (und umgekehrt).
3. **Unabhängige Rotation/Sperrung** (Incident-Response, siehe Sicherheitskonzept).
4. **Modellwahl je Aufgabe:** Routineberichte mit günstigem Modell, Tiefen-Forensik mit starkem Modell — je Aufgabe konfigurierbar.
**Ablage:** beide Keys über die vorhandene `SecretProtection` (F1-Mechanik) verschlüsselt — nicht im
Klartext in DB/Config.
## 6. Sicherheit (Verzahnung mit docs/sicherheit)
- **OpenRouter = NEUER externer Datenempfänger.** Bewusste Erweiterung der Egress-Allowlist (§5.3 im
Sicherheitskonzept) + Dokumentation dort. Es verlassen uns: Trade-/Entscheidungs-/Log-Daten (Wallet-
Adressen sind ohnehin öffentlich on-chain). **Redaction-Schicht vor dem Versand:** niemals Secrets/
Keys/Connection-Strings in Tool-Antworten (Log-Reader filtert Muster; Secrets stehen per F6-Prüfung
ohnehin nicht in Logs — Doppelboden bleibt).
- **Read-only by design:** kein Order-/Schreib-Tool. Damit ist auch Prompt-Injection über Fremdtexte
(Marktfragen in Dossiers) auf „falsche Analyse" begrenzt, kann aber nie handeln.
- Tool-Aufrufe des Agenten werden geloggt (sup_-Tabelle) — der Supervisor ist selbst auditierbar.
## 7. Phasen
- **S-0 Datenfundament (Core):** `core_decision_journal` + ReasonCode-Enum + `SignalId`-Durchreichung +
`core_order_events` + JSONL-Sink + **Log Viewer im Terminal**. Engine/Leiter/Monitor/RF schreiben
strukturiert. Pure Logik + Tests; Migrationen offline. **Sofortnutzen ohne KI** (abfragbare Rejects,
Log-Forensik per CorrelationId, Zielland-Debugging).
- **S-1 Dossier:** Generator (pur, testbar) + Dossier-Browser-UI (Modul-Skelett Supervisor).
- **S-2 Agent:** OpenRouter-Client, Tool-Registry (read-only, transport-agnostisch), Analyse-Chat-Tab
mit **Profil-Auswahl** (zunächst 1 Profil „Allgemein"), Architektur-Kontext-Dokument.
- **S-3 Team & Berichte:** Technik-/Modul-Supervisor-Profile, Batch-Analysen, Counterfactual-Report,
täglicher Threema-Bericht; `IPredictalyticsClient` (Core) + Predictalytics-Tools.
- **S-4 MCP-Light (optional):** Tool-Registry zusätzlich als lokaler MCP-Server für externe Clients.
## 8. Offene Entscheidungen (Richard)
1. **Start mit S-0 sofort?** (Empfehlung: ja — nützt auch ohne KI und VOR dem Live-Start; alles
Weitere baut darauf.)
2. Counterfactual-Tracking („was wäre aus Rejects geworden") von Anfang an im Journal vorsehen
(Resolution-Nachverfolgung abgelehnter Signale) oder später?
3. Modellwahl-Defaults (günstig vs. stark) und Tokenbudget/Monat für den Supervisor.
4. Tagesbericht via Threema gewünscht (S-3)?
5. Text-Log-Sink nach Etablierung des Log Viewers abschalten (nur noch JSONL) oder dauerhaft dual?
6. Predictalytics-API: Auth/Key-Mechanik und welche Endpoints der Supervisor bekommt (read-only-Subset).
## Ergänzungen Richard (2026-07-16, eingearbeitet)
- ✅ Predictalytics-Daten als Analyse-Quelle (§2, `IPredictalyticsClient` im Core, S-3).
- ✅ Supervisor-„Team" — als Profile über einer Infrastruktur statt getrennter Agenten (§4a).
- ✅ Reasoning/Logs KI-freundlich als JSONL + menschenlesbarer Log Viewer im Terminal (§1, S-0).