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:
Richard
2026-07-12 18:34:02 +02:00
co-authored by Claude Fable 5
parent 28e112f128
commit a1fcb4ace5
6 changed files with 264 additions and 28 deletions
+146
View File
@@ -0,0 +1,146 @@
# Predictalytics REST API — Referenz
> Stand: 2026-07-11 · Interne API ohne Authentifizierung (nur lokal betreiben!).
> Interaktive Doku: **`/swagger`** auf dem laufenden Server (Standalone-API und
> WinForms-Embedded-Server registrieren identische Endpoints über
> `ApiConfiguration.MapPredictalyticsEndpoints()` — dort ist die einzige Stelle,
> an der neue Endpoints registriert werden dürfen).
Konventionen: JSON mit camelCase-Feldnamen · Zeiten in UTC (ISO 8601) ·
Prozente auf 0100-Skala · Beträge in USD · `WinRate` ist marktbasiert
(gewonnene abgeschlossene Märkte / abgeschlossene Märkte, nicht pro Trade).
---
## Traders
### `GET /api/traders`
Trader-Liste, sortiert nach CombinedScore, dann TotalPnl.
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| `skip` / `take` | int | 0 / 50 | Paging |
| `platform` | string | All | `Polymarket`, `Limitless`, … |
| `highlyCopyable` | bool | false | nur `CopytradingScore ≥ 60` |
Antwort: Array von **TraderDto**`id`, `platform`, `platformUserId` (Wallet),
`displayName`, `tier`, `strategy`, `combinedScore`, `copytradingScore` (kombinierter
Estimator-Score), `copytradingQualityScore` (LCB-Edge), `copytradingCopyabilityScore`
(Alpha-Decay/Sizing), `winRate`, `totalPnl`, `totalTrades`, `trades30d`, `pnL30d`,
`winRate30d`, `estimatedBankroll`, `isOnWatchlist`, `isSuspectedBot`, `lastPolledAt`.
*Geplant (FIXPLAN D2):* `trait`-Parameter (mehrfach = UND) und `traits`-Feld im DTO.
### `GET /api/traders/{id}`
**TraderDetailDto** — alles aus TraderDto plus: `notes`, `manualPriorityOverride`,
Zeitfenster `pnL7d`/`winRate7d`/`pnL24h`/`winRate24h`, `currentBalance`
(kumulierter Cashflow seit Tracking-Beginn), Teil-Scores `activityScore`/
`qualityScore`/`volumeScore`/`timingScore`, `rank`, `createdAt`,
`aiStrategySummary`, `recentTrades` (letzte 50, **TradeDto**),
`categoryPerformances` (je Kategorie: `category`, `totalVolume`, `totalPnL`,
`totalTrades` = abgeschlossene Märkte, `winningTrades`, `winRate` 01).
**TradeDto:** `id`, `traderId`, `traderName`, `platform`, `dbMarketId`, `marketId`
(ConditionId), `marketQuestion`, `outcome`, `side` (`Buy`/`Sell`/`Redeem`/`Split`/
`Merge`/…), `price`, `size`, `amount`, `executedAt`.
### `GET /api/traders/{id}/deep-dive`
On-the-fly-Analyse über die letzten 500 Trades (lädt bei Bedarf Preis-Historie nach —
langsamster Endpoint). Felder: `classifiedStrategy`, `isSuspectedBot`,
`avgHoldDurationHours`, `avgPositionSizeUsd`, `marketsTraded`, `hedgingFrequency`,
`timingAccuracy`, `entryQuality`, `exitQuality` (je 0100, 50 = neutral),
`botIndicators` (string[]), `summary`, `recentTrades` (100).
### `GET /api/traders/{id}/positions`
Offene und realisierte Positionen. Je **TraderPositionDto**: `marketId`,
`marketName`, `category`, `outcomeToken`, `sharesHeld`, `avgCost`, `realizedPnl`,
`unrealizedPnl`, `currentPrice`, `lastTradeExecutedAt`.
### `POST /api/traders?platform=Polymarket&wallet=0x…`
Trader manuell anlegen (Import + Discovery-Flag). Antwort: Trader-Id.
### `POST /api/traders/{id}/priority?score=…`
Manuellen Prioritäts-Override setzen (ohne `score`: löschen).
### `POST /api/traders/{id}/watchlist` · `DELETE /api/traders/{id}/watchlist`
Watchlist-Zugehörigkeit setzen/entfernen. Watchlist-Trader sind von Retention/
Cleanup ausgenommen und werden bevorzugt synchronisiert/enriched.
### `POST /api/traders/{id}/ai-analysis?manual=true|false`
LLM-Strategie-Analyse anstoßen (synchron; `manual=true` nutzt das teurere Modell).
Antwort: `{ summary }`. Persistiert `aiStrategySummary`, `strategy`, `isSuspectedBot`.
---
## Markets
### `GET /api/markets`
Aktive Märkte. Parameter: `skip`/`take`, `platform`, `category`
(z. B. `Sports`, `Politics`, `Crypto`), `query` (Textsuche in Frage/ConditionId).
Je **MarketDto**: `id`, `platform`, `question`, `volume`, `liquidity`, `endDate`,
`isResolved`.
### `GET /api/markets/{id}`
**MarketDetailDto**: zusätzlich `platformMarketId` (ConditionId), `description`,
`category`, `subcategory`, `resolutionOutcome`, `imageUrl`, `botActivityScore`/
`uniqueTradersCount`/`averageTradeSize` (⚠ derzeit immer 0 — MarketAnalytics wird
noch nicht berechnet), `outcomes` (`name`, `price`), `recentTrades` (50).
---
## Watchlist
### `GET /api/watchlist`
Alle Einträge: `traderId`, `displayName`, `platformUserId`, `platform`, `totalPnl`,
`winRate`, `copytradingScore`, `label`, `notes`, `createdAt`.
---
## Jobs (asynchrone Hintergrund-Aufträge)
Jobs werden von den Workern abgearbeitet (Worker müssen laufen!). Status:
`Pending``InProgress``Completed`/`Failed`.
| Endpoint | Wirkung |
|---|---|
| `GET /api/jobs?skip&take` | Liste, neueste zuerst: `id`, `jobType`, `status`, `traderId`, `traderName`, `createdAt`, `startedAt`, `completedAt`, `errorMessage` |
| `POST /api/jobs/sync/{traderId}` | Trade-Historie synchronisieren (HistorySync) |
| `POST /api/jobs/analyze/{traderId}` | PnL-Engine + Copytrading-Estimator (TraderAnalysis) |
| `POST /api/jobs/deep-resync/{traderId}` | Komplette Historie paginiert neu importieren; löscht vorher COMPACT-Aggregate und alle Positionen des Traders |
| `POST /api/jobs/deep-resync-pruned` | DeepResync-Jobs für alle Trader mit gepruneten Positionen/COMPACT-Trades enqueuen |
| `POST /api/jobs/analyze-backlog?take=50` | TraderAnalysis-Jobs für unanalysierte Trader enqueuen (nie analysiert zuerst, dann nach TotalTrades) |
---
## Dashboard, Suche, Alerts, Sonstiges
| Endpoint | Beschreibung |
|---|---|
| `GET /api/dashboard` | Kennzahlen-Übersicht: `totalTraders`, `activeTraders24h`, `totalTrades`, `volume24h`, `unreadAlerts`, `watchlistCount`, `topTraders` (Top 5 nach PnL7d), `largestTrades` (24h), `recentAlerts`, `platformBreakdown` |
| `GET /api/search?q=…` | Sucht Trader (DisplayName **und** Wallet-Adresse) und Märkte; Antwort `{ traders, markets }` |
| `GET /api/alerts?count&unreadOnly` | Alert-Liste |
| `PUT /api/alerts/{id}/read` | Alert als gelesen markieren |
| `GET /api/health` | `{ status, timestamp }` |
## Dev (Diagnose)
| Endpoint | Beschreibung |
|---|---|
| `GET /api/dev/verify-positions/{traderId}` | Vergleicht unsere `TraderPositions` mit Polymarkets `/positions`-API; Antwort: `mismatches[]`, `match`, `dbPositionsCount`, `apiPositionsCount` |
> Ein früherer `POST /api/dev/repair-db` wurde entfernt (fehlerhaftes SQL,
> destruktiv). Reparatur läuft über den WinForms-Menüpunkt **Development →
> Recalculate All Traders**.
---
## Geplante Erweiterungen (FIXPLAN Teil D/E — für API-Konsumenten relevant)
- `GET /api/traits` + `trait`-Filter auf `/api/traders`; `traits`-Liste in den Trader-DTOs (D2).
- Markt-Rendite-Metriken im Detail-DTO: `medianWinReturnPct`, `avgWinReturnPct`,
`medianLossReturnPct`, `avgLossReturnPct`, `profitFactor` (D2c).
- `GET /api/traders/{id}/profile` — vollständiges Analyse-Profil eines Traders in
einem Aufruf (Kennzahlen + Zeitfenster + Traits + Fingerprint-Verteilungen +
Kopierbarkeits-Aggregate), gedacht für externe Konsumenten wie PolyTrader (Teil E).
- Out-of-Sample-Fenster (A/B), Preisband-Profil, Stop-Loss-Klassifikation,
Portfolio-/Korrelations-Sicht (Teil E).