# 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.
