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:
Richard
2026-08-23 18:56:50 +02:00
co-authored by Claude Opus 5
parent 5507db3e32
commit 6218a04fe4
33 changed files with 569 additions and 129 deletions
@@ -0,0 +1,117 @@
# 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)
1. **Bibliothek:** Nethereum (bereits als Abhängigkeit im Projekt für EIP-712-Signing
vorhanden) — Contract-Calls über die bestehende Alchemy-RPC-Anbindung (Polygon).
2. **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.
3. **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.
4. **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. Sonst `Failed` mit Fehlertext.
5. **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
1. `.agents/rules/clob.md` gilt verschärft: Private-Key-Nutzung außerhalb des
erprobten Order-Signing-Pfads. Jede Phase einzeln committen; RD-3 nie
überspringen.
2. Der Worker fasst NUR Queue-Einträge an — er scannt nie selbst Positionen
(klare Verantwortung: Module erkennen, Core löst ein).
3. Alle Beträge/TxHashes loggen; Threema-Tageszusammenfassung „X Redeems, Y USDC
freigesetzt, Z manuell offen".
4. 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.