- 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>
8.9 KiB
Umsetzungsplan: Modul „BundleArbitrage" (Intra-Market- & NegRisk-Arbitrage)
Stand: 2026-07-06 Ziel: Neues Strategiemodul, das Preissummen-Anomalien innerhalb von Polymarket erkennt und handelt: YES + NO < $1.00 (binäre Märkte) und Summen-Verletzungen in NegRisk-Multi-Outcome-Märkten. Reihenfolge: Nach/parallel zu MarketMaking — nutzt dieselbe Orderbuch- Infrastruktur. Harte Voraussetzung: Phase 1 (Marktdaten-Fundament) aus
UMSETZUNGSPLAN-CopyTrading-Verbesserungen.md. Wichtig: Dieses Modul startet bewusst als reines Mess-Modul (Detection-only). Ob Execution gebaut wird, entscheidet die Messphase.
0. Strategie-Hintergrund & ehrliche Einordnung
Mechanik:
- Binär: Kostet YES + NO zusammen < $1.00 (beide zum Ask kaufbar),
ist der Kauf beider Seiten ein garantierter Gewinn: Das Paar zahlt bei
Resolution sicher $1.00 aus — oder kann on-chain sofort zu $1.00 USDC
zusammengelegt werden (CTF
mergePositions). - NegRisk (Multi-Outcome, genau ein Gewinner): Summe aller YES-Asks < $1.00 → alle YES kaufen (eines zahlt aus). Komplementär: Überteuerte Summen über die NO-Seite bzw. NegRisk-Konvertierungen handeln.
Ehrliche Einordnung (Stand 2026): Auf den großen Märkten ist das ein HFT-Spiel — Fenster von Sekunden, dominiert von spezialisierten Bots; die Taker-Fees seit März 2026 haben viele kleine Anomalien zusätzlich unprofitabel gemacht. Die Chance liegt im Long Tail (kleine/neue Märkte, auf die die großen Bots nicht schauen) und als Beifang der ohnehin laufenden Orderbuch-Streams des MarketMaking-Moduls. Deshalb: erst messen, dann bauen.
Fee-Beachtung: Als Taker fallen je Leg Fees an (kategorieabhängig, 0–1,8 %). Ein Bundle mit 2 ¢ Brutto-Marge kann nach Fees negativ sein. Die Profitrechnung muss Fees je Leg von Anfang an enthalten. Maker-seitige Ausführung (ein Leg ruht als Limit) ist fee-frei, aber nicht atomar.
1. Architektur-Einbettung
Neues Projekt src/PolyTrader.Modules.BundleArbitrage/ als IPolyTraderModule
(Name = "BundleArbitrage", DbPrefix = "ba_"), Registrierung in Program.cs.
Eigener Polymarket-Account (gleiche Begründung wie in den anderen Modul-Plänen; kann sich in v1 den Account mit MarketMaking teilen, sofern die Inventar-Buchführung getrennt bleibt — Empfehlung: eigener Account, sobald Execution live geht).
Persistenz
| Tabelle | Inhalt |
|---|---|
ba_opportunities |
Jede erkannte Anomalie: Zeitpunkt, Markt/Event, Legs mit Preisen & ausführbarer Size, Brutto-/Netto-Marge (nach Fees), Lebensdauer (wann verschwunden) |
ba_executions |
Ausgeführte Bundles: Legs, Fills, Slippage, Ergebnis |
ba_settings |
Schwellen, Size-Limits, Modus (Detect/Execute) |
Die Lebensdauer-Messung („wie lange war die Anomalie ausführbar?") ist der wichtigste Datenpunkt der Messphase — sie entscheidet, ob unsere Ausführungslatenz überhaupt konkurrenzfähig ist.
2. Komponenten
2.1 ArbScannerService : BackgroundService — Detection
Zwei Datenpfade:
- Hot Set (WSS): Für die vom
ClobMarketDataService(Core) ohnehin gestreamten Bücher (MarketMaking-Märkte + Top-Volumen-Märkte) wird bei jedem Book-Update die Summenprüfung getriggert (< 1 ms, pure Funktion). - Long-Tail-Sweep (REST): Zyklischer Scan über aktive Märkte
(Gamma-API-Liste, dann CLOB
GET /bookbzw. Batch-Preis-Endpoints — verfügbare Batch-Endpoints bei Umsetzung in der Doku prüfen). Rate-Limits respektieren (Batching + Delays wie imTraderMonitorService-Muster); Sweep-Frequenz Setting (z. B. alle 60 s für 500 Märkte, priorisiert nach Volumen/Neuheit).
Prüf-Logik (pure, getestete Klasse BundleMath):
- Binär:
bestAskYes + bestAskNo + FeeYes + FeeNo < 1.00 − MinMarginPct. Ausführbare Size = min(AskSize beider Seiten), ggf. über mehrere Book-Level kumuliert (Level-2-Sweep-Rechnung). - NegRisk:
Σ bestAskYes_i + Σ Fees < 1.00 − MinMarginPctüber alle Outcomes eines NegRisk-Events (Event-Gruppierung über Gamma-API;NegRisk-Flag existiert bereits inMarketData). - Jede erkannte Anomalie →
ba_opportunities; bei Verschwinden (nächstes Update unterschreitet Schwelle) Lebensdauer nachtragen.
2.2 Mess-Auswertung (Phase BA-1, entscheidungsrelevant)
Report (UI-Tab + wöchentlicher Threema-Report):
- Anomalien/Tag nach Marge-Bucket (0,5–1 %, 1–2 %, > 2 % netto).
- Verteilung ausführbare Size und Lebensdauer.
- Erwarteter Monatsertrag bei angenommener Erfolgsquote X % = Σ(Netto-Marge × min(Size, unser Limit)) über gefangene Fenster.
Go/No-Go-Kriterium für Execution: erwarteter Ertrag > Entwicklungs- und Kapitalkosten; realistisch fangbare Fenster (Lebensdauer > unsere Latenz, konservativ ≥ 2–3 s).
2.3 ArbExecutionService — nur nach Go-Entscheidung
- Beide Legs gleichzeitig als IOC-artige Orders senden (CLOB-Ordertypen
FOK/FAK bei Umsetzung in der Doku verifizieren;
PolymarketClobClientggf. erweitern). Preis = erkannter Ask + kleiner Puffer, Size = min-Leg. - Single-Leg-Risiko (ein Leg füllt, das andere nicht) ist das
Kernproblem — Behandlungsreihenfolge:
a) Sofortiger Retry des offenen Legs (bis Preis
1.00 − Fees − MinMargin/2). b) Kein Fill → offenes Leg als GTC-Maker-Order zum Break-even-Preis stellen. c) Timeout (Setting, z. B. 10 min) → Leg über Eskalationsleiter abbauen (Muster aus Copytrading-Plan Phase 0.1) und Verlust inba_executionsverbuchen.MaxSingleLegLossUsd-Tageslimit als Kill-Switch. - Size-Limits:
MaxUsdPerBundle(Start 10–25),MaxOpenBundles, Tagesbudget. .agents/rules/clob.mdbeachten — jede CLOB-Client-Erweiterung mit Backup/Commit und Mehrfach-Review.
2.4 Kapital-Recycling: CTF mergePositions (Phase BA-4)
Ohne Merge bindet jedes Bundle Kapital bis zur Resolution (bei kurzlaufenden Märkten oft akzeptabel — Priorisierung im Scanner auf EndDate < 7 Tage umgeht das Problem anfangs).
On-Chain-Merge: YES + NO gleicher Size → $1.00 USDC sofort, via
ConditionalTokens mergePositions(...); NegRisk-Sets über den
NegRisk-Adapter. Implementierung teilt sich Infrastruktur mit dem
Auto-Redeem des ResolutionFarming-Moduls (Phase RF-4) — gemeinsamen
Core-Baustein OnChainCtfService bauen, nicht zweimal implementieren.
Contract-Adressen/ABI aus https://docs.polymarket.com (Developer/CTF)
verifizieren; Gas (POL) -Handling und Balance-Warnung wie im RF-Plan.
2.5 UI
- Tab „Live-Anomalien": aktuelle Opportunities mit Netto-Marge/Size.
- Tab „Messung": Statistik-Report aus 2.2.
- Tab „Executions": Bundles, Single-Leg-Vorfälle, PnL.
- Tab „Settings": Schwellen, Modus-Schalter Detect/Execute (Default: Detect).
3. Phasen & Akzeptanzkriterien
Phase BA-1: Detection-only (2–4 Wochen Messung)
- Scanner (Hot Set + Long-Tail-Sweep),
BundleMathmit Unit-Tests (inkl. Fee-Rechnung, Level-2-Kumulation, NegRisk-Summen),ba_opportunities-Logging, Mess-Report. - Akzeptanz: App baut & läuft; Report nach 2 Wochen vollständig; dokumentierte Go/No-Go-Empfehlung.
Phase BA-2: Execution klein (nur bei Go)
- IOC-Doppel-Leg, Single-Leg-Behandlung, Size-Limits, Kill-Switch.
- Zunächst nur binäre Märkte (NegRisk-Execution ist komplexer → BA-3).
- Akzeptanz: ≥ 20 Bundles ausgeführt; Single-Leg-Quote < 20 %; Netto-PnL nach Fees > 0.
Phase BA-3: NegRisk-Execution
- Multi-Leg-Bundles (N Outcomes), strengere Size-/Slippage-Grenzen (mehr Legs = mehr Single-Leg-Risiko).
Phase BA-4: OnChainCtfService (Merge) — Kapital-Recycling
- Gemeinsam mit ResolutionFarming RF-4 (Redeem) als ein Core-Baustein.
- Testmarkt/Kleinstbetrag zuerst; Akzeptanz: Bundle → USDC ohne manuellen Eingriff, USDC-Delta verifiziert.
4. Risiken & Gegenmaßnahmen
| Risiko | Gegenmaßnahme |
|---|---|
| Anomalien existieren, sind aber in < 1 s weg | Messphase BA-1 entscheidet VOR Entwicklungsaufwand für Execution |
| Single-Leg-Exposure | IOC-Orders, Retry-Kaskade, Tages-Verlustlimit, kleine Bundles |
| Fees fressen Marge | Netto-Rechnung inkl. Fees je Leg von Anfang an; MinMarginPct konservativ (Start ≥ 1 %) |
| Rate-Limits durch Long-Tail-Sweep | Batching, Priorisierung, Sweep-Frequenz drosseln; API-Fehlerquote überwachen |
| Stale-Book-Falsch-Signale | Max-Age-Check auf Book-Daten (TryGetBook(maxAgeMs)); Anomalie erst nach 2 aufeinanderfolgenden Bestätigungen |
| On-Chain-Merge-Fehler | Separater Baustein, Testmarkt, clob.md-Regeln, Balance-Verifikation |
5. Offene Entscheidungen
MinMarginPct(netto, nach Fees) für Detection-Logging (Empfehlung 0,5 %) vs. Execution (Empfehlung ≥ 1 %).- Long-Tail-Sweep-Umfang (alle aktiven Märkte vs. Top-N + Neue) — abhängig von beobachteten Rate-Limits.
- Account-Frage: mit MarketMaking teilen oder eigener (Empfehlung: eigener, sobald BA-2 startet).
- Priorität von BA-4 (Merge): Bei Fokus auf kurzlaufende Märkte zunächst verzichtbar — Kapitalbindung von Tagen ist bei kleinen Größen tragbar.