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>
6.5 KiB
Umsetzungsplan: On-Chain-Auto-Redeem (modulweise schaltbar)
Stand: 2026-07-11 Ziel: Gewonnene Positionen automatisch on-chain einlösen (Shares → USDC), als Core-Baustein mit Aktivierung je Modul. Richards Anforderung: In Testphasen neuer Module soll Auto-Redeem gezielt AUS bleiben können, um die Performance der Entwicklung manuell nachvollziehen zu können — ohne dass andere, etablierte Module ihren Automatismus verlieren. ⚠️ Höchste clob.md-Kritikalität: On-Chain-Signing mit echten Private Keys. Jede Phase: Backup/Commit vorher, Testmarkt/Kleinstbetrag zuerst.
1. Architektur: Queue statt Direktaufruf
Module redeemen nie selbst. Sie melden einlösbare Positionen in eine zentrale Queue; ein Core-Worker arbeitet sie ab — nur für Module, deren Auto-Redeem aktiv ist.
Modul (RF-Monitor, CT-Sync, später DD) PolyTrader.Core
│ erkennt „Position gewonnen & aufgelöst" │
├── IRedeemQueue.Enqueue(RedeemRequest) ─────────────▶│ Tabelle core_redeem_queue
│ (immer! unabhängig vom Schalter) │
│ ▼
│ OnChainRedeemWorker (BackgroundService)
│ • nur Requests von Modulen mit AutoRedeemEnabled
│ • Rest bleibt als "Manual" sichtbar (UI-Liste)
▼ • CTF redeemPositions / NegRiskAdapter
UI je Modul: Pending-Redeems-Ansicht • Verifikation über USDC-Balance-Delta
Warum immer enqueuen: Auch bei deaktiviertem Auto-Redeem entsteht so eine vollständige, je Modul gefilterte „zum Redeem bereit"-Liste (Dashboard/UI) — genau die Übersicht, die Richard in Testphasen für die manuelle Betreuung will. Der Schalter entscheidet nur, ob der Worker sie abarbeitet.
1.1 Datenmodell (core_redeem_queue)
| Feld | Inhalt |
|---|---|
| Id (auto) | PK |
| ModuleName | "ResolutionFarming" / "CopyTrading" / … |
| AccountId, TokenId, ConditionId | Ziel der Einlösung (ConditionId zwingend — für den Contract-Call) |
| IsNegRisk | Adapter-Wahl |
| SizeShares, ExpectedUsd | erwartete Auszahlung (Shares × 1.00) |
| Status | Pending / Processing / Done / Failed / Manual |
| Attempts, LastError, EnqueuedAt, CompletedAt, TxHash | Betrieb/Nachvollziehbarkeit |
1.2 Schalter
- Je Modul:
core_module_settings(oder appsettings-Sektion) —AutoRedeem:ResolutionFarming = false,AutoRedeem:CopyTrading = false(Default IMMER aus; bewusstes Einschalten je Modul). - Global-Not-Aus:
AutoRedeemGlobalEnabled(analog GlobalTradingPaused, Quickbar-Toggle) — schlägt alle Modul-Schalter. - UI: Schalter je Modul in dessen Settings-Tab + Anzeige im Core-Dashboard, welche Module aktiv sind.
2. Der On-Chain-Teil (OnChainCtfService, Core)
- Bibliothek: Nethereum (bereits als Abhängigkeit im Projekt für EIP-712-Signing vorhanden) — Contract-Calls über die bestehende Alchemy-RPC-Anbindung (Polygon).
- Aufrufe: Standard-Markt: ConditionalTokens
redeemPositions(collateral, parentCollectionId=0x0, conditionId, indexSets); NegRisk-Markt: über den NegRisk-Adapter. Contract-Adressen + ABI + indexSets-Ermittlung bei Umsetzung zwingend aus https://docs.polymarket.com (Developer/CTF) verifizieren — nicht aus dem Gedächtnis kodieren. Die USDC-/CTF-Adressen als Konstanten mit Quellenangabe. - Gas: Wallet braucht POL. Vor jedem Call Balance-Check; unter Schwelle
(Setting, z. B. 0.5 POL) → Request auf
Manual+ Threema-Warnung „POL nachfüllen". Gas-Preis: Standard-Estimation, Cap als Setting. - Verifikation = Wahrheit: Ein Redeem gilt erst als
Done, wenn (a) die Tx bestätigt ist UND (b) das USDC-Balance-Delta ≈ ExpectedUsd (Toleranz) gemessen wurde. SonstFailedmit Fehlertext. - Retry: max. 3 Versuche mit Backoff (1/10/60 min), danach
Manual+ Threema. Idempotenz beachten: vor jedem Versuch prüfen, ob die Position on-chain überhaupt noch einlösbar ist (bereits redeemte Shares → als Done werten, nicht als Fehler).
3. Modul-Integration
3.1 ResolutionFarming (erster Nutzer)
FarmingResolutionMonitorService setzt heute RedeemStatus = "Pending" am
RfClosedTrade. Ergänzung: beim Schließen eines Gewinners → IRedeemQueue.Enqueue.
Worker-Callback (oder Status-Poll) aktualisiert RedeemStatus (Pending → Redeemed/
Manual/Failed) → sichtbar im Historie-Tab. Wichtig für Richards Testphasen-
Anforderung: Der realisierte PnL ist bereits bei Resolution gebucht; der Redeem
ändert nur die Kapitalverfügbarkeit. Die Performance-Auswertung bleibt also mit und
ohne Auto-Redeem identisch — nur die Bankroll-Rotation unterscheidet sich.
3.2 CopyTrading (zweiter Nutzer)
Im TraderMonitorService existiert die Stelle bereits: der auskommentierte
Python-Redeem-Block im Resolution-Fallback („bereit für manuellen Redeem")
— dort Enqueue statt Kommentar. Gleicher PnL-Hinweis wie oben.
3.3 Künftige Module
Contract: Ein Modul, das Positionen bis Resolution hält, ruft bei „gewonnen &
aufgelöst" genau einmal Enqueue und liest optional den Status zurück. Mehr nicht.
4. Phasen & Akzeptanzkriterien
| Phase | Inhalt | Akzeptanz |
|---|---|---|
| RD-1 | Queue-Tabelle + IRedeemQueue + Modul-Schalter + UI-Pending-Liste (noch KEIN On-Chain-Code) | Module enqueuen; Liste zeigt je Modul „bereit zum Redeem"; Schalter sichtbar; 100 % ohne Live-API testbar |
| RD-2 | OnChainCtfService gegen Polygon: zuerst READ-only (Balance, Einlösbarkeits-Check) |
Balance-/Zustandsabfragen stimmen gegen Polygonscan |
| RD-3 | Erster echter Redeem: EIN Testmarkt, Kleinstbetrag, manuell getriggert (Button an der Pending-Liste) | Tx bestätigt, USDC-Delta verifiziert, Status Done |
| RD-4 | Worker-Automatik scharf für RF (Schalter an), CT folgt nach Beobachtung | 1 Woche fehlerfreier Betrieb, Failed-Quote < 5 %, POL-Warnung getestet |
5. Leitplanken
.agents/rules/clob.mdgilt verschärft: Private-Key-Nutzung außerhalb des erprobten Order-Signing-Pfads. Jede Phase einzeln committen; RD-3 nie überspringen.- Der Worker fasst NUR Queue-Einträge an — er scannt nie selbst Positionen (klare Verantwortung: Module erkennen, Core löst ein).
- Alle Beträge/TxHashes loggen; Threema-Tageszusammenfassung „X Redeems, Y USDC freigesetzt, Z manuell offen".
- Manuelle Redeems (über die Website) müssen erkannt werden: Einlösbarkeits-Check in 2.5 markiert extern eingelöste Einträge als Done statt Failed.