Files
PolyTraderSharp/UMSETZUNGSPLAN-Modul-ResolutionFarming.md
T
RichardandClaude Opus 4.8 92a88e8be8 Phase 7: Mapping-Randfälle + Parser-/Repo-Randfälle (78 Tests)
- DbContextModelTests: feinkörnige Modell-Invarianten - Dezimal-Präzision (18,6)
  auf Geldfeldern (Core + Settings), MaxLength auf Strings, manuell gesetzte Keys
  (ValueGeneratedNever), AssignedAccountIds hat Value-Converter + text-Spalte,
  MarketData JSON-Spalten = text, Indizes (TradeRecord.ClosedAt,
  MasterTraderHistory TraderId/ClosedAt).
  (GetColumnType() wirft unter InMemory -> Spaltentyp via Relational:ColumnType-
  Annotation ausgelesen.)
- MongoExportParserTests erweitert: numerische statt String-Dezimale, unbekannte
  Felder ignoriert, mehrere Dokumente in Reihenfolge, AssignedAccountIds als
  String-Zahlen, IsActive-Default.
- RepositoryEdgeCaseTests: GetAll leer != null, Update-Alias, Factory-Isolation,
  History-Exists/GetByTraderSince inklusive an den Grenzen.

Alle 78 gruen. (Copytrading-Service-Logik bewusst noch nicht getestet - wird
parallel ueberarbeitet.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 09:16:03 +02:00

213 lines
10 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.
# Umsetzungsplan: Modul „ResolutionFarming" (Favoriten nahe Auflösung)
> Stand: 2026-07-06
> Ziel: Neues Strategiemodul, das systematisch unterbewertete Favoriten
> (~9098 ¢) in bald auflösenden Märkten kauft, bis zur Resolution hält und
> automatisch redeemt.
> Reihenfolge: **Erstes neues Strategiemodul** (geringster Infrastrukturbedarf,
> validiert die Modul-Architektur über Copytrading hinaus).
> Voraussetzung: Phase 0 + 0.2 (Fee-Modell) aus
> `UMSETZUNGSPLAN-CopyTrading-Verbesserungen.md`. Phase 1 (Orderbuch) ist
> hilfreich, aber nicht zwingend für den Start.
---
## 0. Strategie-Hintergrund (Warum das funktioniert)
Auswertungen der Polymarket-Handelsdaten zeigen ein **Favorite-Longshot-
Reversal**: Outcomes mit hoher Wahrscheinlichkeit sind systematisch
*unterbewertet* (Retail überschätzt Longshots und drückt damit den Favoriten-
Preis). Ein 95-¢-Favorit gewinnt im Schnitt öfter als in 95 % der Fälle.
25 % Marge in 2448 h ergibt hohe annualisierte Renditen — **sofern das
Tail-Risiko diszipliniert gemanagt wird**: Ein verlorener 95-¢-Trade
vernichtet ~19 gewonnene. Das Risikomodell IST die Strategie.
Interner Kontext: Die profitabelsten kopierten Master (Typ „SwissTony"/„RN1")
machen genau das — hunderte BUYs, nie SELLs, Auflösung abwarten. Dieses Modul
internalisiert die Strategie und eliminiert die Copy-Latenz und die
Fremdbestimmung der Marktauswahl.
**Fees (seit März 2026):** Taker-Fees je Kategorie (Sports ~0,75 %, Politik
~1,0 %, Krypto ~1,8 %, Geopolitik 0 %) — bei 25 % Brutto-Marge ist die
Kategorie-Wahl entscheidend. Maker-Einstieg (Limit ins Buch) zahlt 0 Fees.
---
## 1. Architektur-Einbettung
Neues Projekt `src/PolyTrader.Modules.ResolutionFarming/` (Class Library,
net8.0-windows), Registrierung als `IPolyTraderModule` analog
`CopyTradingModule` (`Name = "ResolutionFarming"`, `DbPrefix = "rf_"`),
Einbindung in `Program.cs` der App.
### ⚠️ Grundsatzentscheidung: Eigener Polymarket-Account je Strategiemodul
**Dringende Empfehlung:** Das Modul handelt über einen **eigenen Account**
(Multi-Account-Support existiert im Core / `AccountState`).
Begründung: Der `TraderMonitorService` des Copytrading-Moduls synct **alle**
Wallet-Positionen eines Accounts in `account.OpenPositions`, würde
ResolutionFarming-Positionen „adoptieren" (Master-Zuordnungs-Fallbacks),
in seine Limits (PerMarket/PerMaster/Zeitfenster) einrechnen und ggf.
Auto-Redeem-/Cleanup-Logik darauf anwenden. Saubere Trennung über getrennte
Wallets vermeidet diese gesamte Konfliktklasse zur Laufzeit **und**
buchhalterisch (PnL je Strategie sauber messbar).
In der UI/Settings des Moduls: Zuordnung `AccountId ↔ Modul` mit Warnung,
wenn derselbe Account auch im Copytrading aktiv ist.
### Persistenz (EF Core / Pomelo / MySQL, eigener DbContext analog `CopyTradingDbContext`)
| Tabelle | Inhalt |
|---|---|
| `rf_settings` | Modul-Settings je Account (Preisband, Budgets, Limits) |
| `rf_candidates` | Scanner-Ergebnisse (Markt, Preis, Score, Filtergründe) — auch abgelehnte, für spätere Kalibrierung |
| `rf_positions` | Offene Farming-Positionen (TokenId, Entry, Size, EndDate, ClusterKey, Status) |
| `rf_closed_trades` | Abgeschlossene Trades inkl. Fees, Redeem-Infos |
Zusätzlich schreibt das Modul in den generischen Core-Trade-Log
(modulübergreifendes Dashboard).
---
## 2. Komponenten
### 2.1 `MarketScannerJob : BackgroundService`
Alle 1015 Minuten (JobManager-Registrierung wie `MasterTraderAnalyticsJob`,
manuell triggerbar):
1. Gamma-API: aktive Märkte mit `endDate < now + MaxHoursToResolution`
(Default 48 h), nicht closed. Bestehenden `PolymarketApiService` erweitern
(Query-Parameter für endDate-Fenster; Endpoint-Details bei Umsetzung aus
https://docs.polymarket.com verifizieren).
2. Je Markt den Favoriten bestimmen (Outcome mit höchstem Preis). Preisquelle:
CLOB Midpoint/Book (REST `GET /book` bzw. `IOrderBookProvider`, falls
Phase 1 des Copytrading-Plans schon umgesetzt).
3. Filterkette (jeder Reject wird mit Grund in `rf_candidates` geloggt):
- Preisband: `MinPrice ≤ ask ≤ MaxPrice` (Default 0.900.98).
- Liquidität: Ask-Tiefe am Zielpreis ≥ geplante Ordergröße × Faktor;
zusätzlich Markt-Volumen/Liquiditätsfelder der Gamma-API als Grobfilter.
- Kategorie-Whitelist (Default: Sports, Geopolitik, Politik; **Krypto
ausschließen** — 1,8 % Fee frisst die Marge; keine 15-Min-/Stunden-Märkte).
- Netto-Edge-Check: `(1 ask) Fee(ask, Kategorie) ≥ MinEdgePct`
(Default z. B. 1,5 %).
- Blacklist-Mechanismus (Slugs/Tags), z. B. für Marktarten mit
Resolution-Streitigkeiten (UMA-Disputes).
4. Kandidaten mit Score in `rf_candidates` schreiben; Anzeige in der Modul-UI.
### 2.2 Risiko-Engine (pure, testbare Klasse `FarmingRiskEngine`)
Settings je Account (`rf_settings`):
| Setting | Default | Bedeutung |
|---|---|---|
| `MaxPerMarketUsd` | 25 | Max. Einsatz je Markt |
| `MaxPerClusterPct` | 10 % | Max. Anteil der Bankroll je **Ereignis-Cluster** |
| `MaxTotalExposurePct` | 60 % | Max. Gesamteinsatz in offenen Positionen |
| `MaxNewPositionsPerDay` | 20 | Drosselung |
| `MinEdgePct` | 1.5 % | Netto-Edge nach Fees |
| `DailyLossKillSwitchUsd` | konfig. | Tagesverlust → Modul pausiert + Threema |
**Cluster-Definition (kritisch!):** 20 Fußballspiele desselben Spieltags sind
keine 20 unabhängigen Wetten. ClusterKey ableiten aus Event-/Series-Slug der
Gamma-API (z. B. Liga+Datum, Turnier, Wahl-Event). Korrelierte Favoriten
(z. B. „Kandidat X gewinnt" + „Partei von X gewinnt") teilen einen Cluster.
Erste Version: Heuristik über Event-Slug; Verfeinerung später.
### 2.3 `FarmingExecutionService`
1. Einstieg **Maker-first**: GTC-Limit auf Best-Bid bzw. Mid 1 Tick
(0 Fees). Kein Fill nach T Minuten (Default 15) → Entscheidung per Setting:
Taker-Fill (wenn Netto-Edge auch mit Fee noch ≥ MinEdge) oder verwerfen.
2. Order-Verwaltung über `PolymarketClobClient` (Core), Tracking analog
`PendingOrderTimestamps`-Muster des Copytrading-Moduls.
3. Positionen in `rf_positions` + Core-Positions-Sync gegen die Wallet
(Data-API `positions` — Muster aus `TraderMonitorService.PollLiveAccountsAsync`
übernehmen, aber schlanker: kein Master-Mapping nötig).
### 2.4 `ResolutionMonitorJob` + `AutoRedeemService`
1. Monitor: prüft offene `rf_positions` gegen Resolution
(`PolymarketApiService.CheckMarketResolutionAsync` existiert bereits).
2. **On-Chain-Auto-Redeem** (heute im gesamten Projekt nur manuell — dieser
Baustein nützt auch dem Copytrading):
- Gewinner-Shares einlösen via ConditionalTokens-Contract auf Polygon
(`redeemPositions(...)`); für NegRisk-Märkte über den NegRisk-Adapter.
**Contract-Adressen und Aufrufparameter bei Umsetzung zwingend aus der
offiziellen Doku verifizieren** (https://docs.polymarket.com,
Developer-Sektion CTF/NegRisk).
- Implementierung: Nethereum-Paket ODER Raw-RPC über die vorhandene
Alchemy-Anbindung; Signing mit dem Account-PrivateKey (liegt in
`AccountState`).
- Gas: Wallet braucht POL; Balance-Check + Threema-Warnung bei Unterdeckung.
- Retry mit Backoff; Erfolg = USDC-Balance-Delta verifiziert.
- `.agents/rules/clob.md` gilt hier besonders: On-Chain-Signing ist
hochkritisch — zuerst mit Kleinstbetrag auf einem Testmarkt verifizieren.
3. Übergangslösung bis 2.4 fertig: PreRedeem-artiger Verkauf (GTC-Limit 0.99+)
oder manueller Redeem — das Modul funktioniert auch ohne On-Chain-Teil,
bindet dann nur Kapital länger.
### 2.5 UI (`RegisterUi`, ein Fenster mit Tabs analog `CopyTradingMainForm`)
- Tab „Kandidaten": aktueller Scan mit Filtergründen (auch Rejects).
- Tab „Positionen": offene Farming-Positionen, Cluster-Auslastung, Countdown.
- Tab „Historie/Statistik": Winrate je Preisband (Kalibrierung!), Netto-PnL,
Fees, Redeem-Status.
- Tab „Settings": PropertyGrid auf `rf_settings` (Muster `AccountSettingsView`).
---
## 3. Phasen & Akzeptanzkriterien
### Phase RF-1: Modul-Skelett + Scanner (read-only)
- Projekt, Modul-Registrierung, DbContext + Migration, Scanner-Job, UI-Tab
„Kandidaten". **Keine Order-Platzierung.**
- Akzeptanz: App baut & startet mit Modul; Scanner liefert plausible
Kandidaten; Rejects nachvollziehbar geloggt; 1 Woche Kandidaten-Sammlung.
### Phase RF-2: Demo-Betrieb (4 Wochen)
- Execution im Demo-Modus (realistisches Fill-Modell: Ask-Preis + Fee,
siehe Copytrading-Plan Phase 4.2). Risiko-Engine aktiv.
- Akzeptanz/Go-Kriterium für Live: Kalibrierungstabelle zeigt
`realisierte Winrate je Preisband > Preisband-Mitte` und
Netto-Edge nach Fees > 0 über ≥ 100 Demo-Trades.
### Phase RF-3: Live klein
- Eigener Account, kleines Budget (z. B. 200500 USDC), `MaxPerMarketUsd` 510.
- Kill-Switch + Threema-Reporting (Tageszusammenfassung) aktiv.
- Akzeptanz: 2 Wochen Live ohne Ausführungsfehler; Live-Ergebnis im Rahmen
der Demo-Erwartung.
### Phase RF-4: Auto-Redeem on-chain
- Wie 2.4; zuerst Testmarkt/Kleinstbetrag, dann aktivieren.
- Akzeptanz: Gewinner-Position wird ohne manuellen Eingriff zu USDC.
### Phase RF-5: Kalibrierung & Skalierung
- Scoring von Heuristik auf Daten umstellen: historische Winrate je
Preisband × Kategorie aus `rf_candidates`/`rf_closed_trades` (+ optional
öffentliche Polymarket-Historien-Datensätze) → nur Bänder/Kategorien mit
nachgewiesenem Edge handeln. Budget stufenweise erhöhen.
---
## 4. Risiken & Gegenmaßnahmen
| Risiko | Gegenmaßnahme |
|---|---|
| Tail-Event (Favorit verliert) | Cluster-Limits, MaxPerMarket, Diversifikation über Kategorien |
| Korrelierte Cluster falsch geschnitten | Konservative Cluster-Heuristik, Review der Cluster in der UI |
| Resolution-Disputes (UMA) | Blacklist strittiger Marktarten; nur klare, objektiv auflösbare Märkte |
| Fee-Änderungen | Fee je Trade persistieren, MinEdge-Check dynamisch |
| Konflikt mit Copytrading-Sync | Eigener Account (Abschnitt 1) |
| On-Chain-Redeem-Fehler | Separate Phase, Testmarkt zuerst, Balance-Verifikation, clob.md-Regeln |
## 5. Offene Entscheidungen
1. Eigener Account: neuer Polymarket-Account nötig — wer legt ihn an, wie viel
Startkapital?
2. Preisband-Default (0.900.98) und `MinEdgePct` — mit Demo-Daten validieren.
3. Nethereum vs. Raw-RPC für On-Chain-Calls (Empfehlung: Nethereum, weniger
Fehlerfläche beim ABI-Encoding).
4. Taker-Fallback beim Einstieg erlauben oder strikt Maker-only?