API audit: expose 7d/24h windows, remove broken repair-db, add API docs
- TraderDetailDto now exposes PnL7d/WinRate7d/PnL24h/WinRate24h and CurrentBalance — the engine has computed these all along but the API never delivered them. - Removed POST /api/dev/repair-db: its raw SQL referenced non-existent columns/tables (Trades.Type/Payout, Traders.LastPositionsUpdatedAt, table "Jobs") and would have deleted ALL TraderPositions including pruned-history conserves. The supported repair path is the WinForms "Recalculate All Traders" action. - Swagger tags for Jobs and Dev groups; full endpoint reference in docs/API.md (kept generic — external consumers like PolyTrader adapt to our API, not vice versa). - FIXPLAN Teil E: master-selection gap analysis as generic extensions (profile endpoint, out-of-sample window metrics, price-band profile with per-band win rate, stop-loss ratio, copyability aggregates with category fees, correlation endpoint, martingale trait). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
28e112f128
commit
a1fcb4ace5
@@ -506,3 +506,105 @@ gegen 300+/min) — das Trade-Replay-PnL ist für diese Klasse bereits falsch un
|
||||
4. Tägliches DB-Wachstum sichtbar reduziert (DB-Size-Anzeige im WinForms-Statusbar beobachten).
|
||||
|
||||
Reihenfolge: **D1 → D2/D2b/D2c → D3** (D2c ist klein und gehört in denselben Engine-Durchlauf wie die Winrate; bei D3 zuerst Tier C, dann Tier B).
|
||||
|
||||
---
|
||||
|
||||
## Teil E — Master-Auswahl-Metriken & generischer Profil-Endpoint (ergänzt 2026-07-11)
|
||||
|
||||
> Hintergrund: Ein externer Konsument (PolyTrader-Copytrading) braucht eine belastbare
|
||||
> Master-Trader-Auswahl (Prüfplan liegt in `PREDICTALYTICS-PRUEFPLAN-Master-Auswahl.md` im
|
||||
> PolyTraderSharp-Repo). **Bewusste Architektur-Entscheidung: Die API bleibt generisch.**
|
||||
> Kein PolyTrader-spezifisches Format, kein „HOLDER/STOPLOSS"-Vokabular in der API —
|
||||
> wir exponieren neutrale Metriken, der Konsument mappt selbst.
|
||||
> Abgleich: M2/M8 existieren (D2c/CategoryPerformances), M3/M9 teilweise als Traits (D2),
|
||||
> M1/M5/M6 teilweise; **komplett neu sind M4, M7, Out-of-Sample-Fenster, Kopierbarkeits-
|
||||
> Aggregate und die Korrelations-Sicht** — das ist Teil E.
|
||||
|
||||
### E1. Generischer Profil-Endpoint `GET /api/traders/{id}/profile`
|
||||
|
||||
Ein Aufruf liefert das vollständige Analyse-Profil (statt 4+ Einzel-Calls):
|
||||
Stammdaten + alle Analytics-Felder + Traits (D2) + Rendite-Metriken (D2c) +
|
||||
Fenster-Blöcke (E2) + Fingerprint-Verteilungen (E3) + Kopierbarkeits-Aggregate (E5).
|
||||
Nur persistierte Werte ausliefern (kein On-the-fly-Rechnen wie im Deep-Dive) —
|
||||
der Endpoint muss schnell und pollbar sein. In `docs/API.md` dokumentieren.
|
||||
|
||||
### E2. Fenster-Metriken als Struktur + Out-of-Sample-Vergleich
|
||||
|
||||
**Problem:** Die 24h/7d/30d-Felder sind Einzelspalten; der Prüfplan braucht zwei frei
|
||||
definierte Vergleichsfenster (z. B. Tag −180…−60 vs. −60…heute), um Glücks-Wallets
|
||||
auszusortieren (nur wer in BEIDEN Fenstern liefert, ist ein Kandidat).
|
||||
|
||||
**Fix:**
|
||||
- Neue Tabelle `TraderWindowMetrics`: TraderId, WindowStart, WindowEnd, ClosedMarkets,
|
||||
WinRate, AvgReturnPct (M1: Ø realisierte Rendite je Markt), MedianWinReturnPct,
|
||||
MedianLossReturnPct, ProfitFactor, ComputedAt. Unique (TraderId, WindowStart, WindowEnd).
|
||||
- Berechnung im Analytics-Lauf für zwei konfigurierbare Fenster
|
||||
(`AnalysisWindows`-Sektion in appsettings, Default: −180…−60 und −60…0 Tage).
|
||||
Wiederverwendet die D2c-Logik mit Zeitfilter auf den Markt-Abschlusszeitpunkt.
|
||||
- Im Profil (E1) als `windows[]`-Array. **Achtung Retention:** Fenster A reicht weiter
|
||||
zurück als 90 Tage — Berechnung muss mit fehlender Historie ehrlich umgehen
|
||||
(`closedMarkets` klein → Konsument sieht die dünne Stichprobe). Nach der
|
||||
Retention-Verlängerung auf 180 Tage (D3) wird Fenster A tragfähig.
|
||||
|
||||
### E3. Fingerprint-Verteilungen (persistiert, im Profil)
|
||||
|
||||
Im Analytics-Lauf berechnen und als JSON-Spalte(n) auf `TraderAnalytics` oder eigene
|
||||
Tabelle persistieren:
|
||||
- **Preisband-Profil (M7):** Einsatz-Anteil je 10-¢-Einstiegspreisband über Buys,
|
||||
**plus realisierte Winrate je Band** (macht Glück von System unterscheidbar:
|
||||
„kauft 90–95-¢-Shares, gewinnt 97 %" = +Edge sichtbar pro Band).
|
||||
- **Haltedauer:** Median (nicht nur Ø) Stunden Kauf→Exit/Auflösung (M6).
|
||||
- **Positionsgrößen:** P50/P90-Amount (M9-Basis).
|
||||
- Trade-Frequenz je Woche (aus Trades30d ableitbar, im Profil ausgeben).
|
||||
|
||||
### E4. Exit-Verhalten klassifizieren (M4) — generisch als Trait + Kennzahl
|
||||
|
||||
- Kennzahl `stop_loss_ratio`: Anteil der Sells, die nach einem Preisrückgang von
|
||||
≥ 10 % unter den Einstands-AvgCost erfolgen (Sell-Preis ≤ 0,9 × AvgCost),
|
||||
bezogen auf alle geschlossenen Positionen. Braucht KEINE Preis-Historie —
|
||||
Sell-Preis vs. AvgCost der Position reicht als v1-Näherung.
|
||||
- Traits: `sells_at_loss` (Ratio > 0,15) ergänzt das vorhandene `holds_to_resolution`.
|
||||
Ein Konsument bildet daraus selbst HOLDER (`holds_to_resolution` ∧ ¬`sells_at_loss`),
|
||||
STOPLOSS, MIXED.
|
||||
|
||||
### E5. Kopierbarkeits-Aggregate (im Profil)
|
||||
|
||||
- `medianMarketVolumeUsd`: Median des `Market.Volume` (bzw. Volume24h) der vom Trader
|
||||
gehandelten Märkte — handelt er in Kleinstmärkten, bewegt der Kopierer den Preis.
|
||||
- `medianPostFillDriftPct`: Median-Preisänderung nach seinen Buys (aus vorhandenem
|
||||
`TradeContext.PriceAfter1m`/`FollowerFillPrice60s`, nur enriched Trades; Anzahl
|
||||
der Datenpunkte mit ausgeben).
|
||||
- `netEdgeAfterFeesPct`: `AvgReturnPct` (E2, Fenster B) minus kategorie-gewichteter
|
||||
Taker-Fee (aus `Market.FeeRateBps` — wird bereits erfasst!) minus konfigurierbarem
|
||||
Spread-Aufschlag (`CopyCostSettings:SpreadPct`, Default 2,0). Generisch als
|
||||
„Netto-Edge nach Kopierkosten" benannt.
|
||||
|
||||
### E6. Korrelations-/Portfolio-Sicht
|
||||
|
||||
- Neuer Endpoint `GET /api/traders/correlation?ids=1,2,3` (oder `?top=20`):
|
||||
paarweise Jaccard-Ähnlichkeit über die gehandelten ConditionIds (Fenster B) +
|
||||
Kategorie-Mix-Cosinus. Antwort: Matrix + je Paar die Overlap-Zahl.
|
||||
- Kein „Portfolio-Empfehlungs"-Endpoint in v1 — die Auswahl-Logik (max. 2 je
|
||||
Kategorie etc.) gehört zum Konsumenten. Wir liefern die Korrelationsdaten.
|
||||
|
||||
### E7. Martingale-Erkennung (M9) als Trait
|
||||
|
||||
`martingale_pattern`: mittleres Verhältnis Einsatz(nach verlorenem Markt) /
|
||||
Einsatz(nach gewonnenem Markt) über die Sequenz der abgeschlossenen Märkte;
|
||||
Trait ab Verhältnis ≥ 1,5 bei ≥ 20 Märkten. (Einsatz = investiertes Kapital je
|
||||
Markt aus D2c.)
|
||||
|
||||
### E8. Abnahme Teil E
|
||||
|
||||
1. Bestehende Tests grün (Assertions unverändert) + neue Tests: Fenster-Metriken
|
||||
(bekannte Markt-Menge, zwei Fenster → korrekte Werte je Fenster), Preisband-
|
||||
Winrate (Band-Zuordnung + Ränder 0,895/0,90), `stop_loss_ratio`
|
||||
(Positiv-/Negativfall), Jaccard-Berechnung, Martingale (steigende Einsätze nach
|
||||
Losses → Trait; konstante → kein Trait).
|
||||
2. `GET /api/traders/{id}/profile` liefert für einen analysierten Trader alle Blöcke
|
||||
gefüllt; Antwortzeit < 200 ms (nur persistierte Daten).
|
||||
3. `docs/API.md` um Profile-/Correlation-Endpoint ergänzt.
|
||||
4. Kein PolyTrader-spezifisches Vokabular in API/DTOs.
|
||||
|
||||
Reihenfolge: E1+E3 zuerst (Profil mit vorhandenen + Fingerprint-Daten), dann E2
|
||||
(Fenster), E4/E5/E7 (Kennzahlen), E6 zuletzt. Teil E setzt D1/D2/D2c voraus.
|
||||
|
||||
Reference in New Issue
Block a user