Erster Commit des bestehenden monolithischen WinForms-Copytraders, inklusive der Alt-Backups (*.bak), damit diese dauerhaft in der Historie rekonstruierbar bleiben. Threema-Lib unter libs/ wurde vendored (nested .git entfernt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
282 lines
14 KiB
Markdown
282 lines
14 KiB
Markdown
# Umsetzungsplan: Modularisierung PolyTraderSharp
|
||
|
||
> Stand: 2026-07-01
|
||
> Ziel: Umbau des monolithischen WinForms-Copytraders in ein modulares System
|
||
> mit einem schlanken **Core** und unabhängigen **Modulen**. Erstes Modul: **Copytrading**.
|
||
|
||
---
|
||
|
||
## 1. Leitprinzipien
|
||
|
||
1. **Core kennt keine Module.** Der Core stellt nur Basis-Infrastruktur bereit
|
||
(Host, DB/Persistenz, Settings, Jobs, Logging, API-Clients, Benachrichtigungen,
|
||
Modul-Contract). Er hat **keine** Referenz auf irgendein Modul.
|
||
2. **Module hängen nicht voneinander ab.** Jedes Modul referenziert nur den Core.
|
||
Ein Modul kennt kein anderes Modul. Dies wird durch getrennte Projekte
|
||
**zur Compile-Zeit erzwungen**.
|
||
3. **Jede Phase lässt die App lauffähig und baubar zurück.** Kein „Big Bang".
|
||
Nach jeder Phase: Debug-Build grün, App startet, Copytrading funktioniert.
|
||
4. **WinForms bleibt.** Die GUI-Anforderung ist fix. Module tragen ihre eigenen
|
||
UI-Tabs zur Shell bei.
|
||
5. **Sicherheit vor Geschwindigkeit beim Refactoring.** CLOB-Integration ist
|
||
hochkritisch (siehe `.agents/rules/clob.md`) – bei Berührung besonders sorgfältig,
|
||
jede Änderung mehrfach prüfen. Rollback jederzeit über Git möglich.
|
||
|
||
---
|
||
|
||
## 2. Zielarchitektur
|
||
|
||
### 2.1 Solution-Struktur (Multi-Projekt)
|
||
|
||
```
|
||
PolyTraderSharp.sln
|
||
│
|
||
├── PolyTrader.Core (Class Library, net8.0-windows)
|
||
│ • Generic Host / Bootstrap-Infrastruktur
|
||
│ • Persistenz: Repository-Interfaces + Implementierung (EF Core)
|
||
│ • Settings (appsettings.json + IOptions) + Core-Settings-Sektion
|
||
│ • JobManager, Logging (TerminalLogger / ILogger-Sink)
|
||
│ • Polymarket-Infrastruktur: PolymarketApiService, PolymarketClobClient,
|
||
│ PolymarketWssClient, AlchemyWebsocketService
|
||
│ • Querschnitt: MullvadVpnService, ThreemaService
|
||
│ • Eigene Trading-Accounts (AccountState) — die Konten, mit denen WIR traden
|
||
│ • Generischer Trade-Log (modulübergreifend auswertbar)
|
||
│ • Gesamt-Dashboard (Overview über alle Module)
|
||
│ • Core-State (generisch): MarketCache, globale Betriebsschalter
|
||
│ • IPolyTraderModule-Contract + Modul-Registry
|
||
│
|
||
├── PolyTrader.Modules.CopyTrading (Class Library, net8.0-windows)
|
||
│ • TraderMonitorService (Signalquelle)
|
||
│ • CopyTradingEngine (Ausführung)
|
||
│ • MasterTraderAnalyticsJob, TraderAnalyticsJob
|
||
│ • Models: TrackedTrader (kopierte Master-Trader), CopySignal,
|
||
│ CopyTradeRecord, TraderAnalyticsResult, MasterTraderHistoryRecord
|
||
│ • Copytrading-State: Traders (Master), MasterTraderPositions,
|
||
│ PendingOrderTimestamps, TraderAnalyticsCache
|
||
│ • Channels: CopySignal, ClosedTrade
|
||
│ • Eigener Copytrading-Trade-Log (Detail-Auswertung kopierter Trades,
|
||
│ zusätzlich zum generischen Core-Log)
|
||
│ • Eigene UI-Tabs (Master/Slave-Verwaltung, Modul-Analyse, Closed Trades)
|
||
│ • Eigene Modul-Settings-Sektion
|
||
│ • CopyTradingModule : IPolyTraderModule
|
||
│
|
||
├── PolyTrader.App (WinForms .exe, net8.0-windows)
|
||
│ • Program.cs: Host-Bootstrap, lädt Core + registrierte Module
|
||
│ • Shell-Form (frm_main reduziert auf Rahmen: Terminal, Jobs, Settings-Tab)
|
||
│ • Referenziert Core + alle aktiven Module
|
||
│
|
||
└── PolyTrader.Tests (xUnit, optional — spätere Phase)
|
||
• Risk-/Entscheidungslogik des Copytrading-Moduls
|
||
```
|
||
|
||
### 2.2 Modul-Contract (Entwurf)
|
||
|
||
```csharp
|
||
public interface IPolyTraderModule
|
||
{
|
||
string Name { get; } // "CopyTrading"
|
||
string DbPrefix { get; } // Namespace für DB-Objekte, z.B. "ct_"
|
||
|
||
void RegisterServices(IServiceCollection services, IConfiguration config);
|
||
void RegisterUi(IModuleUiHost uiHost); // Modul hängt seine Tabs ein
|
||
Task StartAsync(CancellationToken ct); // läuft NACH Core-Hydration
|
||
Task StopAsync(CancellationToken ct);
|
||
}
|
||
```
|
||
|
||
- **Discovery:** Die App registriert Module explizit in `Program.cs`
|
||
(`services.AddPolyTraderModule<CopyTradingModule>()`). Kein Runtime-Assembly-Scanning
|
||
(bewusst einfach gehalten; kann später zum Plugin-System ausgebaut werden).
|
||
- **Feature-/Lizenz-Gating:** `IPolyTraderModule` ist die natürliche Schnittstelle,
|
||
um Module später per Lizenz zu aktivieren/deaktivieren (vgl. `lizenssystem.md`).
|
||
|
||
### 2.3 State-Aufteilung
|
||
|
||
`TradingState` wird zerlegt:
|
||
|
||
| Feld | Ziel |
|
||
|------|------|
|
||
| `MarketCache` | **Core** (generischer Markt-Cache) |
|
||
| `GlobalTradingPaused`, `LiveTradingMode`, `DemoTradingMode` | **Core** (globale Betriebsschalter) |
|
||
| `Accounts` (unsere eigenen Trading-Accounts, `AccountState`) | **Core** — die Konten, mit denen WIR traden; modulübergreifend nutzbar |
|
||
| `Traders` (kopierte Master-Trader, `TrackedTrader`) | **CopyTrading-Modul** |
|
||
| `MasterTraderPositions`, `PendingOrderTimestamps`, `TraderAnalyticsCache`, `TotalCopyTrades`, `GlobalPnl` | **CopyTrading-Modul** |
|
||
|
||
> Entschieden (2026-07-01): Eigene Trading-Accounts liegen im **Core** (auch künftige
|
||
> Module handeln über dieselben Konten). Die **kopierten** Master-Trader (`TrackedTrader`)
|
||
> sind ein Copytrading-Konzept und liegen im **Modul**.
|
||
|
||
### 2.4 Trade-Logging (zweistufig)
|
||
|
||
Zwei unabhängige, parallel geführte Logs:
|
||
|
||
1. **Generischer Core-Trade-Log** (`TradeRecord` + `ITradeLogRepository`):
|
||
modulneutrale Felder (ModulName, AccountId, Markt, Side, Entry/Exit, PnL, Zeiten,
|
||
ExitReason). Ermöglicht die **modulübergreifende** Gesamtauswertung. Jedes Modul,
|
||
das Trades ausführt, schreibt hier einen Eintrag.
|
||
2. **Copytrading-spezifischer Log** (`CopyTradeRecord`, im Modul): erweitert die
|
||
generischen Felder um Copytrading-Details (`SourceTraderId`, `SourceTraderName`,
|
||
Master-Adresse, Signal-Herkunft) für die **detaillierte** Copytrading-Analyse.
|
||
|
||
Beim Schließen eines kopierten Trades schreibt das Modul **beides**: einen generischen
|
||
Eintrag in den Core-Log und einen Detaileintrag in seinen eigenen Log.
|
||
|
||
### 2.5 Dashboard & Analyse
|
||
|
||
- **Core-Gesamt-Dashboard:** Overview über alle Module (aggregierte PnL, Kontostände,
|
||
offene Positionen, grobe Kennzahlen je Modul) — gespeist aus dem generischen Core-Log.
|
||
- **Modul-Analyse:** Jedes Modul liefert seine eigene Detailansicht (Copytrading:
|
||
Trader-Winrates, kopierte Trades, Master-Performance) — gespeist aus dem Modul-Log.
|
||
|
||
### 2.6 Settings
|
||
|
||
- **Core-Settings-Sektion:** globale/Infrastruktur-Einstellungen (DB, VPN, Threema,
|
||
Betriebsschalter).
|
||
- **Modul-Settings-Sektion:** jedes Modul trägt seine eigene Sektion zum Settings-Tab bei
|
||
(analog zu den UI-Tabs), registriert über den `IPolyTraderModule`-Contract.
|
||
|
||
---
|
||
|
||
## 3. Persistenz-Strategie
|
||
|
||
- **Zielrichtung: Wechsel auf MySQL** via **EF Core + Pomelo.EntityFrameworkCore.MySql**,
|
||
gekapselt hinter Repository-Interfaces im Core.
|
||
- **Begründung:** DB liegt off-hot-path (Live-Pfad ist RAM-only) → kein Performance-Nachteil.
|
||
Gewinn: saubere relationale Tabellen statt Collection-per-Account + Shim, ACID,
|
||
EF-Migrations, Standard-Backups.
|
||
- **Risikoarm durch Reihenfolge:** Zuerst Repository-Abstraktion einziehen (Phase 3),
|
||
MySQL-Umstieg als eigene späte Phase (Phase 6). Die Modularisierung ist davon
|
||
entkoppelt und nicht blockiert.
|
||
- **Aufräumen:** LiteDB-Paket, `data.db` und `MongoDbLiteDBShim` entfallen nach der Migration.
|
||
- **ORM: Entity Framework Core** (entschieden) — Migrations + wenig Boilerplate.
|
||
|
||
---
|
||
|
||
## 4. Phasenplan
|
||
|
||
> Jede Phase endet mit grünem Debug-Build + lauffähiger App + Git-Commit.
|
||
|
||
### Phase 0 — Fundament: Versionskontrolle & Aufräumen *(kritisch, zuerst)*
|
||
- [ ] `git init`, sinnvolle `.gitignore` (bin/, obj/, .vs/, *.user, data.db, *.db, server_settings.xml, agentspace/antigravity/).
|
||
- [ ] Alle `.bak*`-Dateien entfernen (CopyTradingEngine, PolymarketClobClient,
|
||
TraderMonitorService, PolymarketWssClient, ClosedTrade.cs.bak_livesync).
|
||
- [ ] Tote Stubs entfernen: `services/database.cs`, `services/settings.cs`, `polymarket/*.cs`.
|
||
- [ ] Baseline-Commit („Ausgangszustand vor Modularisierung").
|
||
|
||
### Phase 1 — Multi-Projekt-Gerüst anlegen *(noch ohne Code-Verschiebung)*
|
||
- [ ] Drei Projekte anlegen: `PolyTrader.Core`, `PolyTrader.Modules.CopyTrading`,
|
||
`PolyTrader.App` (umbenanntes/abgeleitetes bestehendes WinForms-Projekt).
|
||
- [ ] Referenzen: App → Core + CopyTrading; CopyTrading → Core; Core → nichts.
|
||
- [ ] NuGet-Pakete auf Projekte verteilen (Hosting/Http/Nethereum → Core, etc.).
|
||
- [ ] Threema-Lib-Referenz in den Core hängen.
|
||
- [ ] **Ergebnis:** baut, App startet unverändert (Code liegt vorerst weiter im App-Projekt).
|
||
|
||
### Phase 2 — Konfiguration externalisieren
|
||
- [ ] `appsettings.json` einführen (Mongo/MySQL-Connection, DB-Name, Alchemy-Key,
|
||
Mullvad-Account, Threema-Defaults).
|
||
- [ ] `IConfiguration`/`IOptions<T>` verdrahten; hart codierte Strings aus `Program.cs`
|
||
und `ServerSettings`-Defaults entfernen.
|
||
- [ ] Startup-Cleanup-Hack aus `Main()` (DeleteMany ObjectId) entfernen/kapseln.
|
||
|
||
### Phase 3 — Persistenz-Abstraktion (DB noch Mongo)
|
||
- [ ] Repository-Interfaces im Core definieren (`IAccountRepository`,
|
||
`IPositionRepository`, `IMarketRepository`, `ITradeLogRepository` (generisch),
|
||
und im Modul `ICopyTradeLogRepository` + `ITraderRepository`).
|
||
- [ ] Bestehende Mongo/Shim-Zugriffe hinter diese Interfaces ziehen (eine Implementierung).
|
||
- [ ] Direkte `GetCollection<>()`-Aufrufe aus Services/Engine/UI durch Repositories ersetzen.
|
||
- [ ] **Ergebnis:** Kein direkter DB-Zugriff mehr außerhalb der Repository-Schicht.
|
||
|
||
### Phase 4 — Core herauslösen
|
||
- [ ] Infrastruktur-Services nach `PolyTrader.Core` verschieben: Persistenz, Settings,
|
||
JobManager, Logging, PolymarketApiService, PolymarketClobClient, PolymarketWssClient,
|
||
AlchemyWebsocketService, MullvadVpnService, ThreemaService, SnapshotService.
|
||
- [ ] `TradingState` aufteilen (Core-State vs. Modul-State, siehe 2.3).
|
||
- [ ] `IPolyTraderModule`-Contract + Modul-Registry + Bootstrap im Core.
|
||
- [ ] **Startup-Reihenfolge-Fix:** State-Hydration (heute `frm_main.LoadDatabaseAndState`)
|
||
in einen Core-Bootstrap ziehen, der **vor** dem Start der Module/Trading-Services läuft.
|
||
Trading-Services dürfen nicht mehr gegen leeren State anlaufen.
|
||
- [ ] **Ergebnis:** Core baut eigenständig; App nutzt Core.
|
||
|
||
### Phase 5 — CopyTrading-Modul herauslösen
|
||
- [ ] Nach `PolyTrader.Modules.CopyTrading` verschieben: TraderMonitorService,
|
||
CopyTradingEngine, MasterTraderAnalyticsJob, TraderAnalyticsJob, zugehörige Models,
|
||
Copytrading-State, `CopySignal`/`ClosedTrade`-Channels.
|
||
- [ ] Copytrading-UI-Tabs aus `frm_main` in das Modul auslagern (Master/Slave-Verwaltung,
|
||
Modul-Analyse, Closed Trades). `frm_main` wird zur reinen Shell (Terminal, Jobs,
|
||
Core-Gesamt-Dashboard, Settings-Rahmen).
|
||
- [ ] `CopyTradingModule : IPolyTraderModule` implementieren (Services + UI-Tabs +
|
||
Settings-Sektion + Modul-Log + Start/Stop).
|
||
- [ ] Dualen Trade-Log verdrahten: beim Schließen kopierter Trades in Core-Log **und**
|
||
Copytrading-Log schreiben.
|
||
- [ ] Latenten Collection-Namensbug beheben (`traders` vs. `trackers`).
|
||
- [ ] **Ergebnis:** Copytrading ist ein eigenständiges, entfernbares Modul.
|
||
|
||
### Phase 6 — MySQL-Migration
|
||
- [ ] EF Core + Pomelo einrichten; relationales Schema modellieren
|
||
(u.a. `positions` mit `account_id` statt Collection-per-Account;
|
||
`trader_accounts` Join-Tabelle für `AssignedAccountIds`).
|
||
- [ ] Zweite Repository-Implementierung (MySQL) hinter den bestehenden Interfaces.
|
||
- [ ] Einmaliges Migrationsskript Mongo → MySQL (agentspace/scripts).
|
||
- [ ] Umschalten per Konfiguration; Mongo/LiteDB/Shim + `data.db` entfernen.
|
||
|
||
### Phase 7 — Nacharbeiten *(optional, später zu priorisieren)*
|
||
- [ ] Test-Projekt: Risk-/Entscheidungslogik als reine Funktionen extrahieren & testen.
|
||
- [ ] God-Methoden splitten (`PollLiveAccountsAsync`, `ProcessAccountOrderAsync`);
|
||
duplizierte Closed-Trade-Erzeugung zentralisieren.
|
||
- [ ] Leere `catch {}` durch gezieltes Logging ersetzen.
|
||
- [ ] Secrets-Verschlüsselung (DPAPI) für PrivateKey/ApiSecret/ApiPassphrase.
|
||
- [ ] TerminalLogger auf `Microsoft.Extensions.Logging` + UI-Sink umstellen.
|
||
|
||
---
|
||
|
||
## 5. Datei-→-Ziel-Zuordnung (Referenz)
|
||
|
||
| Aktuell | Ziel |
|
||
|---------|------|
|
||
| `Program.cs` | PolyTrader.App |
|
||
| `frm_main.*` | PolyTrader.App (Shell) + Copytrading-Tabs → Modul |
|
||
| `frm_analytics.*` | PolyTrader.Modules.CopyTrading |
|
||
| `TradingState.cs` | aufgeteilt: Core + Modul |
|
||
| `services/PolymarketApiService.cs` | Core |
|
||
| `services/PolymarketClobClient.cs` | Core |
|
||
| `services/PolymarketWssClient.cs` | Core |
|
||
| `services/AlchemyWebsocketService.cs` | Core |
|
||
| `services/MullvadVpnService.cs`, `mullvad.cs` | Core |
|
||
| `services/ThreemaService.cs` | Core |
|
||
| `services/JobManager.cs`, `TerminalLogger.cs`, `logging.cs` | Core |
|
||
| `services/PersistenceService.cs` | Core (generischer Trade-Log-Writer); Copytrading-Detail-Writer → Modul |
|
||
| `services/MarketSyncService.cs`, `SnapshotService.cs` | Core |
|
||
| `Extensions/MongoDbLiteDBShim.cs` | Core (temporär), entfällt in Phase 6 |
|
||
| `services/CopyTradingEngine.cs` | Modul |
|
||
| `services/TraderMonitorService.cs` | Modul |
|
||
| `services/MasterTraderAnalyticsJob.cs`, `TraderAnalyticsJob.cs` | Modul |
|
||
| `Models/AccountState.cs`, `Position.cs`, `MarketData.cs`, `ServerSettings.cs`, `JobStatusRow.cs`, `DashboardRow.cs` | Core |
|
||
| `Models/ClosedTrade.cs` | aufgeteilt: generischer `TradeRecord` → Core, `CopyTradeRecord` (mit SourceTrader-Feldern) → Modul |
|
||
| `Models/TrackedTrader.cs`, `CopySignal.cs`, `TraderAnalyticsResult.cs`, `MasterTraderHistoryRecord.cs` | Modul |
|
||
| `services/database.cs`, `settings.cs`, `polymarket/*.cs` | löschen (Phase 0) |
|
||
| `*.bak*` | löschen (Phase 0) |
|
||
|
||
---
|
||
|
||
## 6. Getroffene Entscheidungen (2026-07-01)
|
||
|
||
1. **Eigene Trading-Accounts → Core**, **kopierte Master-Trader → Copytrading-Modul.**
|
||
2. **Zweistufiges Trade-Logging:** generischer Core-Log (modulübergreifend) **und**
|
||
zusätzlicher Copytrading-Detail-Log im Modul (siehe 2.4).
|
||
3. **ORM: Entity Framework Core.**
|
||
4. **Dashboard:** Core liefert Gesamt-Overview über alle Module; Module liefern
|
||
eigene Detail-Analysen (siehe 2.5).
|
||
5. **Settings:** getrennte Core- und Modul-Settings-Sektionen (siehe 2.6).
|
||
|
||
---
|
||
|
||
## 7. Risiken & Gegenmaßnahmen
|
||
|
||
- **CLOB-Regression:** Höchstes Risiko. Gegenmaßnahme: CLOB-Client möglichst unverändert
|
||
in den Core verschieben (nur Namespace/Referenzen), keine Logikänderung in der
|
||
Umstrukturierungsphase.
|
||
- **Startup-Race weiterhin aktiv, bis Phase 4:** Bis der Startup-Fix greift, bleibt das
|
||
bestehende Verhalten – kein neues Risiko, aber früh angehen.
|
||
- **Datenmigration (Phase 6):** Server läuft produktiv. Migration mit Read-Only-Export +
|
||
Verifikation vor Umschaltung; Rollback-Pfad (Mongo bleibt bis Verifikation bestehen).
|