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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b8d2c8094b
commit
92a88e8be8
@@ -0,0 +1,187 @@
|
||||
# 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:
|
||||
1. **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).
|
||||
2. **Long-Tail-Sweep (REST):** Zyklischer Scan über aktive Märkte
|
||||
(Gamma-API-Liste, dann CLOB `GET /book` bzw. Batch-Preis-Endpoints —
|
||||
verfügbare Batch-Endpoints bei Umsetzung in der Doku prüfen).
|
||||
Rate-Limits respektieren (Batching + Delays wie im
|
||||
`TraderMonitorService`-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 in `MarketData`).
|
||||
- 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
|
||||
|
||||
1. **Beide Legs gleichzeitig** als IOC-artige Orders senden (CLOB-Ordertypen
|
||||
FOK/FAK bei Umsetzung in der Doku verifizieren; `PolymarketClobClient`
|
||||
ggf. erweitern). Preis = erkannter Ask + kleiner Puffer, Size = min-Leg.
|
||||
2. **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 in `ba_executions`
|
||||
verbuchen. `MaxSingleLegLossUsd`-Tageslimit als Kill-Switch.
|
||||
3. Size-Limits: `MaxUsdPerBundle` (Start 10–25), `MaxOpenBundles`,
|
||||
Tagesbudget.
|
||||
4. `.agents/rules/clob.md` beachten — 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), `BundleMath` mit 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
|
||||
|
||||
1. `MinMarginPct` (netto, nach Fees) für Detection-Logging (Empfehlung 0,5 %)
|
||||
vs. Execution (Empfehlung ≥ 1 %).
|
||||
2. Long-Tail-Sweep-Umfang (alle aktiven Märkte vs. Top-N + Neue) — abhängig
|
||||
von beobachteten Rate-Limits.
|
||||
3. Account-Frage: mit MarketMaking teilen oder eigener (Empfehlung: eigener,
|
||||
sobald BA-2 startet).
|
||||
4. Priorität von BA-4 (Merge): Bei Fokus auf kurzlaufende Märkte zunächst
|
||||
verzichtbar — Kapitalbindung von Tagen ist bei kleinen Größen tragbar.
|
||||
Reference in New Issue
Block a user