Eine Roadmap statt fuenfzehn Plandokumente; Altbestand ins Archiv
Der Status des Projekts stand verstreut in elf Umsetzungsplaenen, drei Konzepten, der Linux-Analyse und dem Projektstand - teils widersprechend, teils wochenlang veraltet. Ab jetzt gibt es genau eine Statusquelle. docs/ROADMAP.md (neu): - Alle Vorhaben in vier Stufen A bis D, plus technische Schuld und Verlauf. Die Stufen sind eine Reihenfolge, keine Termine: jede schafft die Voraussetzung fuer die naechste. - Statuszeichen: erledigt / offen / blockiert (mit Ursache) / bewusst zurueckgestellt / Idee, nicht beschlossen. Damit ist das, was wir NICHT bauen wollen, sichtbar vorgehalten statt unauffindbar in einem Plan zu schlummern. - Inhaltlich getragen, nicht nur verlinkt: je Vorhaben Ziel, Phasen, Akzeptanzkriterien, offene Entscheidungen und Leitplanken aus den Quelldokumenten. - Sichtbar gemacht, was vorher zwischen den Dokumenten verborgen lag: CopyTrading Phase 1 ist der Engpass der gesamten Roadmap (MarketMaking und BundleArbitrage haben harte Voraussetzungen darauf), und die Sniper-Metriken aus Phase 3.2 sind ein Spezialfall des StrategieDrift-Fingerprints - zusammen bauen statt doppelt. Archiv (docs/archiv/): - 15 Dokumente verschoben (11 Umsetzungsplaene, 3 Konzepte, ANALYSE-Linux-Portierung). Sie bleiben die Bauanleitungen mit Code-Bezuegen, Risikotabellen und Begruendungen - eingefroren ist nur ihr Status. - archiv/README.md ordnet jedes Dokument seinem Roadmap-Punkt zu. Verweise nachgezogen - der eigentliche Aufwand: - 25 Markdown-Links repariert. 15 davon verschiebungsbedingt (eine Ebene tiefer), der Rest war schon vorher falsch: die Ideensammlung verlinkte Quellcode relativ zum Repo-Wurzelverzeichnis statt zu docs/. - 12 Dateien ausserhalb von docs/ verwiesen in Kommentaren auf die Plaene (csproj, props, setup.json, sechs Quelldateien) - alle auf archiv/ umgebogen. - Verweise auf Dateien, die der Fruehjahrsputz geloescht hat (Ui/, Program.cs, WindowMenuBar), zu Klartext entschaerft statt tote Links zu lassen. - Gegenprobe: 85 Links geprueft, 0 kaputt. Build gruen, 476 Tests gruen. PROJEKTSTAND.md entdoppelt: Abschnitt "Offen" verweist jetzt auf die Roadmap. Arbeitsteilung ist damit klar - Projektstand sagt was IST, Roadmap was KOMMT. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# Umsetzungsplan: Modul „MarketMaking" (Liquidity Rewards + Spread)
|
||||
|
||||
> Stand: 2026-07-06
|
||||
> Ziel: Neues Strategiemodul, das beidseitige Limit-Orders in belohnungs-
|
||||
> berechtigten Polymarket-Märkten stellt und drei Ertragsquellen kombiniert:
|
||||
> tägliche Liquidity Rewards (USDC), Maker-Rebates und den Spread selbst.
|
||||
> Reihenfolge: Nach ResolutionFarming. **Harte Voraussetzung:** Phase 1
|
||||
> (Marktdaten-Fundament: `ClobMarketDataService`, `ClobUserChannelService`)
|
||||
> aus `UMSETZUNGSPLAN-CopyTrading-Verbesserungen.md`.
|
||||
|
||||
---
|
||||
|
||||
## 0. Strategie-Hintergrund
|
||||
|
||||
Polymarket zahlt täglich (00:00 UTC) USDC-Rewards an Wallets, die kompetitive
|
||||
Resting-Limit-Orders in berechtigten Märkten stellen. Der Reward-Pool liegt
|
||||
2026 bei > $5 M/Monat (Sport-Peaks ~$8 M). Die Formel belohnt: Nähe zum
|
||||
Midpoint (innerhalb eines markt-spezifischen Max-Spreads), Ordergröße
|
||||
(Mindestgröße je Markt) und beidseitige Tiefe (einseitige Orders scoren
|
||||
reduziert). Seit den Taker-Fees (März 2026) gibt es zusätzlich ein
|
||||
**Maker-Rebate-Programm** (Anteil der Taker-Fees wird täglich an Maker
|
||||
ausgeschüttet). Maker zahlen selbst keine Fees.
|
||||
|
||||
**Referenzen (bei Umsetzung Formel/Parameter aktuell verifizieren):**
|
||||
- https://docs.polymarket.com/market-makers/liquidity-rewards
|
||||
- https://docs.polymarket.com/trading/fees (Maker-Rebates)
|
||||
- Reward-Parameter je Markt (Max-Spread, Min-Size, Tages-Pool) kommen aus der
|
||||
Gamma-/CLOB-API am Markt-Objekt.
|
||||
|
||||
**Warum dieses Modul strategisch wertvoll ist:** Es ist die einzige Strategie,
|
||||
bei der wir nicht gegen schnellere Bots um denselben Trade konkurrieren —
|
||||
Anwesenheit wird bezahlt. Ertrag ist stetig statt direktional.
|
||||
|
||||
**Hauptrisiko: Adverse Selection.** Unsere Quotes werden bevorzugt dann
|
||||
gefüllt, wenn jemand mit besserer Information (News-Bot, Live-Sport-Feed)
|
||||
gegen uns handelt. Gegenmaßnahmen: Marktauswahl (ruhige, langlaufende Märkte;
|
||||
anfangs KEINE Live-Sport- und KEINE Krypto-Kurzfrist-Märkte), Inventar-Limits,
|
||||
Volatilitäts-Pause.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architektur-Einbettung
|
||||
|
||||
Neues Projekt `src/PolyTrader.Modules.MarketMaking/` als `IPolyTraderModule`
|
||||
(`Name = "MarketMaking"`, `DbPrefix = "mm_"`), Registrierung in `Program.cs`.
|
||||
|
||||
**Eigener Polymarket-Account zwingend** (gleiche Begründung wie im
|
||||
ResolutionFarming-Plan, hier noch kritischer: Der Copytrading-
|
||||
`TraderMonitorService` würde MM-Inventar als Positionen adoptieren und der
|
||||
Copytrading-`CancelConflictingOrdersAsync`-Mechanismus würde unsere
|
||||
Resting-Quotes canceln!).
|
||||
|
||||
### Persistenz
|
||||
|
||||
| Tabelle | Inhalt |
|
||||
|---|---|
|
||||
| `mm_settings` | Globale + je-Markt-Settings (Size, Spread-Ziel, Limits) |
|
||||
| `mm_markets` | Kuratierte/gescorte Märkte (Reward-Parameter, Status) |
|
||||
| `mm_quotes_log` | Quote-Historie (Preis, Size, Dauer, Cancel-Grund) — für Reward-Optimierung |
|
||||
| `mm_fills` | Fills mit Seite, Preis, Inventar danach |
|
||||
| `mm_daily_pnl` | Tagesabrechnung: Rewards, Rebates, Spread-PnL, Inventar-PnL |
|
||||
|
||||
---
|
||||
|
||||
## 2. Komponenten
|
||||
|
||||
### 2.1 `MarketSelectorJob` — Marktauswahl & Scoring
|
||||
|
||||
Täglich + manuell triggerbar:
|
||||
1. Reward-berechtigte Märkte über Gamma-/CLOB-API listen (Felder: Reward-Pool/
|
||||
Rate, `rewardsMaxSpread`, `rewardsMinSize` — Feldnamen verifizieren).
|
||||
2. Score je Markt: `erwarteter Reward pro gequoteter $ ÷ Risiko-Proxy`.
|
||||
- Reward-Schätzung: Tages-Pool des Markts ÷ beobachtete konkurrierende
|
||||
Maker-Liquidität innerhalb des Max-Spreads (aus Orderbuch-Snapshots).
|
||||
- Risiko-Proxy: realisierte Midpoint-Volatilität (Stddev der Mid-Bewegungen
|
||||
über 24 h aus `ClobMarketDataService`-Daten), Zeit bis Resolution
|
||||
(je näher, desto gefährlicher), Kategorie.
|
||||
3. Harte Ausschlüsse (erste Ausbaustufe): Live-Sport (in-play), Krypto-
|
||||
Kurzfrist-Märkte (15 min/1 h), Märkte < 7 Tage vor EndDate, Midpoint
|
||||
außerhalb 0.10–0.90 (Extrempreise = asymmetrisches Inventarrisiko).
|
||||
4. Output: Ranking in `mm_markets` + UI; Betreiber aktiviert Märkte manuell
|
||||
(Whitelist-Prinzip — der Bot wählt in v1 nicht selbst).
|
||||
|
||||
### 2.2 `QuotingEngine : BackgroundService` — Kern des Moduls
|
||||
|
||||
Je aktivem Markt eine Quote-State-Machine:
|
||||
|
||||
1. **Zielquote:** Bid und Ask symmetrisch um den Midpoint, Abstand
|
||||
`QuoteSpreadTicks` (Setting), immer **innerhalb** des Reward-Max-Spreads;
|
||||
Size ≥ Reward-Min-Size (Setting `QuoteSizeUsd`, initial klein).
|
||||
2. **Requote-Trigger:** Midpoint-Bewegung > Schwelle (z. B. 1 Tick), eigene
|
||||
Order gefüllt, Reward-Fenster verletzt. Requote = Cancel + neue Order über
|
||||
`PolymarketClobClient`.
|
||||
3. **Churn-Begrenzung:** Mindest-Ruhezeit zwischen Requotes (z. B. 3–5 s),
|
||||
Hysterese (nicht bei jedem Tick nachziehen) — API-Rate-Limits und
|
||||
Order-Spam vermeiden.
|
||||
4. **Fill-Verarbeitung:** über `ClobUserChannelService` (Echtzeit). Nach Fill:
|
||||
Inventar aktualisieren, Gegenquote anpassen (siehe 2.3).
|
||||
5. Alle Quotes/Cancels in `mm_quotes_log` (Grundlage für Optimierung).
|
||||
|
||||
Die Preis-/Requote-Logik als **pure, getestete Klasse** (`QuoteCalculator`)
|
||||
implementieren — Input: Book-Snapshot, Inventar, Settings; Output: Ziel-Quotes.
|
||||
Unit-Tests in `PolyTrader.Tests` (das ist die kritischste Logik des Moduls).
|
||||
|
||||
### 2.3 `InventoryManager` — Risikosteuerung
|
||||
|
||||
1. Inventar je Markt = Netto-Shares (YES-äquivalent) × Preis.
|
||||
2. **Skew:** Bei wachsendem Inventar Quotes asymmetrisch verschieben
|
||||
(Kaufseite weiter weg, Verkaufsseite näher/attraktiver), Faktor
|
||||
proportional zu `Inventar / MaxInventoryUsd`.
|
||||
3. **Limits (Settings je Markt + global):**
|
||||
- `MaxInventoryUsd` je Markt (Default klein, z. B. 50).
|
||||
- `MaxTotalInventoryUsd` über alle Märkte.
|
||||
- Bei Limit-Bruch: Quoting nur noch auf der abbauenden Seite
|
||||
(„Reduce-Only-Modus") bis Inventar < 50 % des Limits.
|
||||
4. **Exit vor Resolution:** Ab `ExitHoursBeforeEnd` (Default 48 h) Reduce-Only,
|
||||
ab 24 h aktiver Abbau (Maker-seitig, notfalls Taker mit Verlust-Deckel).
|
||||
5. **Volatilitäts-Pause:** Midpoint-Sprung > X % in Y Sekunden → alle Quotes
|
||||
des Markts canceln, Cooldown Z Minuten (News-Schutz). Global-Kill-Switch
|
||||
analog `GlobalTradingPaused`.
|
||||
|
||||
### 2.4 `RewardTracker`
|
||||
|
||||
1. Tägliche Reward-/Rebate-Eingänge erkennen (USDC-Transfers auf die Wallet
|
||||
via Data-API/Alchemy) und `mm_daily_pnl` zuordnen.
|
||||
2. Tagesabrechnung: `Rewards + Rebates + SpreadPnL + InventarPnL(mark-to-mid)
|
||||
− Verluste = Netto`. Threema-Tagesreport.
|
||||
3. Kennzahl je Markt: **Reward-ROI pro gequoteter $** → Feedback in den
|
||||
`MarketSelectorJob` (schlechte Märkte deaktivieren).
|
||||
|
||||
### 2.5 UI
|
||||
|
||||
- Tab „Märkte": Kandidaten-Ranking, aktiv/inaktiv-Toggle, Reward-Parameter.
|
||||
- Tab „Live": aktuelle Quotes, Inventar je Markt (Ampel), letzte Fills.
|
||||
- Tab „Abrechnung": `mm_daily_pnl`-Historie, Reward-ROI je Markt.
|
||||
- Tab „Settings": PropertyGrid.
|
||||
|
||||
---
|
||||
|
||||
## 3. Phasen & Akzeptanzkriterien
|
||||
|
||||
### Phase MM-1: Fundament-Verifikation + Selector (read-only)
|
||||
- Voraussetzung prüfen: `ClobMarketDataService`/`ClobUserChannelService`
|
||||
laufen stabil (mehrtägiger Soak-Test, Reconnect-Verhalten).
|
||||
- `MarketSelectorJob` + UI-Ranking, keine Orders.
|
||||
- Akzeptanz: Ranking plausibel; Orderbuch-Daten für Top-Märkte lückenlos
|
||||
über 72 h (Basis für Volatilitäts-Proxy).
|
||||
|
||||
### Phase MM-2: Paper-Quoting (Messung Adverse Selection)
|
||||
- QuotingEngine läuft vollständig, sendet aber **keine** Orders; simulierte
|
||||
Fills: Quote gilt als gefüllt, wenn der Marktpreis durch unser Quote-Level
|
||||
handelt (aus Market-Channel-Trades ableitbar).
|
||||
- 2 Wochen laufen lassen. Messen: simulierter Spread-PnL, Inventarverläufe,
|
||||
Wie oft wären wir „überfahren" worden (Fill unmittelbar vor großer
|
||||
Gegenbewegung)?
|
||||
- Akzeptanz/Go-Kriterium: simuliertes Inventar bleibt innerhalb der Limits;
|
||||
Spread-PnL ≥ 0 (Rewards kommen on top und sind der eigentliche Ertrag).
|
||||
- **Hinweis:** Rewards selbst lassen sich nicht simulieren — sie erfordern
|
||||
echte Resting-Orders. Paper-Phase misst nur die Risikoseite.
|
||||
|
||||
### Phase MM-3: Live auf 1–2 ruhigen Märkten
|
||||
- Eigener Account, kleines Kapital (z. B. 300–500 USDC), `QuoteSizeUsd`
|
||||
knapp über Reward-Min-Size, 1–2 langlaufende Politik-/Geopolitik-Märkte.
|
||||
- Akzeptanz nach 2–4 Wochen: tägliche Rewards fließen nachweislich
|
||||
(`mm_daily_pnl`); Netto (Rewards + Spread − Inventarverluste) > 0;
|
||||
keine Order-Leichen (Cancel-Fehler) im CLOB.
|
||||
|
||||
### Phase MM-4: Skalierung + Skew-Feintuning
|
||||
- Mehr Märkte (Selector-getrieben), Inventar-Skew-Parameter aus Fill-Daten
|
||||
optimieren, Size je Markt anhand Reward-ROI erhöhen.
|
||||
|
||||
### Phase MM-5 (optional): Reward-Optimierung
|
||||
- Order-Laddering (mehrere Level innerhalb des Max-Spreads), dynamische
|
||||
Spread-Wahl abhängig von Konkurrenz-Liquidität, Teilnahme an
|
||||
Sponsor-/Sonder-Reward-Programmen (z. B. Sport-Events pre-game).
|
||||
|
||||
---
|
||||
|
||||
## 4. Risiken & Gegenmaßnahmen
|
||||
|
||||
| Risiko | Gegenmaßnahme |
|
||||
|---|---|
|
||||
| Adverse Selection durch News-/Latenz-Bots | Marktauswahl (keine Live-Events), Volatilitäts-Pause, kleine Size |
|
||||
| Inventar läuft in Resolution | Exit-Regeln ab 48 h/24 h vor EndDate (2.3) |
|
||||
| Order-Churn → Rate-Limits/Sperren | Requote-Hysterese, Mindest-Ruhezeit, Monitoring der API-Fehlerquote |
|
||||
| Reward-Regeländerungen | Parameter täglich aus API lesen, nichts hartkodieren |
|
||||
| WSS-Ausfall → blinde Quotes | Watchdog: keine Book-Updates > N s → alle Quotes canceln (Fail-Safe) |
|
||||
| Konflikt mit Copytrading | Eigener Account (Abschnitt 1) |
|
||||
|
||||
Der Fail-Safe „bei Datenverlust alles canceln" ist Pflicht ab MM-3 und muss
|
||||
getestet werden (WSS künstlich trennen).
|
||||
|
||||
## 5. Offene Entscheidungen
|
||||
|
||||
1. Startmärkte (Empfehlung: 1–2 langlaufende Politik-/Geopolitik-Märkte mit
|
||||
mittlerem Volumen — genug Reward-Pool, wenig Newsflow).
|
||||
2. `QuoteSizeUsd`/Kapital für MM-3.
|
||||
3. Beidseitig quoten von Anfang an (voller Reward-Score) oder zunächst
|
||||
einseitig konservativ? (Empfehlung: beidseitig, dafür kleine Size —
|
||||
einseitig scored schlechter und halbiert den Lerneffekt.)
|
||||
Reference in New Issue
Block a user