18 KiB
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
- 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.
- 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.
- 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.
- WinForms bleibt. Die GUI-Anforderung ist fix. Module tragen ihre eigenen UI-Tabs zur Shell bei.
- 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)
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:
IPolyTraderModuleist 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:
- 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. - 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.dbundMongoDbLiteDBShimentfallen 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 (ABGESCHLOSSEN 2026-07-01)
git init(Branchmain),.gitignore(bin/, obj/, .vs/, *.user, *.db, server_settings.xml, agentspace/antigravity/, .claude/settings.local.json).- Alle 11
.bak*-Dateien entfernt (per-fim Baseline-Commit475d396archiviert, danach entfernt → rekonstruierbar). - Tote Stubs entfernt:
services/database.cs,services/settings.cs,polymarket/*.cs. - Threema-Lib unter
libs/vendored (nested.gitentfernt). - Baseline-Commit
475d396+ Cleanup-Commitf76ad73; Debug-Build 0 Fehler verifiziert.
Phase 1 — Multi-Projekt-Gerüst anlegen (ABGESCHLOSSEN 2026-07-01, Commit 4f130ff)
- Drei Projekte:
PolyTrader.App(umbenanntes WinForms-Projekt, Root),src/PolyTrader.Core,src/PolyTrader.Modules.CopyTrading(net8.0-windows). - Referenzen: App → Core + CopyTrading; CopyTrading → Core; Core → nichts.
- App-csproj:
src\**vom Globbing ausgeschlossen (keine Glob-Kollision); RootNamespace aufPolyTraderSharpgepinnt (schützt .resx/Namespaces). - Threema-Lib-Referenz bleibt im App-Projekt (wandert in Phase 4 zu Bedarf in Core).
- Ergebnis: Solution-Build 0 Fehler, Code liegt weiterhin im App-Projekt.
- Offen für spätere Phasen: NuGet-Pakete beim Code-Umzug auf Core/Modul verteilen.
Phase 2 — Konfiguration externalisieren (ABGESCHLOSSEN 2026-07-01, Commit e312fbb)
appsettings.jsoneingeführt (Mongo-Connection + DB-Name), Copy-to-Output.DatabaseOptionsim Core, viaIOptions<T>gebunden; hart codierte Strings ausProgram.csentfernt.- Startup-Cleanup-Hack aus
Main()entfernt und gekapselt nach Host-Build über die konfigurierte DB neu verankert. - Offen (bewusst später): Alchemy-Key / Mullvad-Account / Threema bleiben vorerst
im GUI-editierbaren
server_settings.xml(kein Konflikt mit Settings-Tab).
Phase 3 — Persistenz-Abstraktion (DB noch Mongo) (IN ARBEIT)
- 3a (
8b3264f): Core-ModelleAccountState/Position/MarketDatain den Core verschoben (NamespacePolyTraderSharp.Modelsbeibehalten), MongoDB.Driver-Paket im Core. - 3b (
ed5d6e3): Repository-Interfaces + Mongo-Implementierungen im Core (IAccountRepository,IMarketRepository,IPositionRepository),AddCorePersistence(). - 3c (
7197f9b): Unkritische Call-Sites migriert (MarketSyncService, PolymarketWssClient). - 3d — Hot-Path (
a0e367e,0c6fc6a): TraderMonitorService + CopyTradingEngine aufIPositionRepository/IMarketRepository/IAccountRepositoryumgestellt._dbaus CopyTradingEngine komplett entfernt; Verhalten unverändert. - frm_main-UI: Account/Market/Demo-Position-Zugriffe → wird zusammen mit der UI-Zerlegung in Phase 5 migriert (vermeidet Wegwerf-Arbeit).
- Offen für Phase 5: generisches
ITradeLogRepository(Core) +ICopyTradeLogRepository+ITraderRepository(Modul), sobaldClosedTrade/TrackedTraderins Modul wandern. - Ergebnis (Ziel): Kein direkter DB-Zugriff mehr außerhalb der Repository-Schicht.
Phase 4 — Core herauslösen (IN ARBEIT)
- 4.1 (
9039af8): TerminalLogger, JobManager, JobStatusRow → Core; toten Stublogging.csgelöscht. - 4.2 (
eebe992): PolymarketClobClient → Core (+ Nethereum.Web3), reines Verschieben. - 4.3 (
8c126cd): ServerSettings → Core. - 4.4 (
a1ce3fc):IPolyTraderModule-Contract im Core (UI-Teil auf Phase 5 vertagt). - 4.5 (
c88eac5): Startup-Reihenfolge-Fix —StartupHydrationService(IHostedService, als erster registriert) hydriert Accounts/Trader vor den Trading-Services;frm_main.LoadDatabaseAndStateentfernt. - 4.6a (
9c068b4): CopySignal + PolymarketApiService → Core. - 4.7 (
0ffc041): MullvadVpnService + ThreemaService (+ Threema-Lib-Ref) → Core; toter Stubmullvad.csgelöscht. - BLOCKIERT durch TradingState-Split (→ Phase 5): MarketSyncService,
AlchemyWebsocketService, PolymarketWssClient, SnapshotService nutzen
TradingState(MarketCache/Accounts/globale Flags). Sie können erst nach dem Split in den Core. - Ergebnis: Core baut eigenständig und enthält jetzt: Modelle (Account/Position/ Market/CopySignal/JobStatusRow/ServerSettings), Repository-Schicht, Config, Logging, JobManager, CLOB-Client, API-Service, Mullvad, Threema, IPolyTraderModule.
Stand nach Phase 4: Der Core ist substanziell und eigenständig. Was noch in der App liegt:
Modul-Services (TraderMonitor, CopyTradingEngine, Analytics-Jobs), die TradingState-abhängige
Infra (MarketSync, Alchemy, WSS, Snapshot), PersistenceService, StartupHydrationService,
der Shim, TradingState, frm_main und die Modul-Modelle (TrackedTrader, TraderAnalyticsResult,
MasterTraderHistoryRecord, ClosedTrade, DashboardRow). Der TradingState-Split ist der
Dreh- und Angelpunkt für Phase 5.
Entscheidung (2026-07-01):
CopySignalwird ein Core-Typ (generisches Markt-Trade- Signal). Das entkoppelt die Polymarket-Infrastruktur sauber in den Core. Der Channel/Workflow bleibt Copytrading. Umbenennung zuTradeSignaloptional/später.
Phase 5 — CopyTrading-Modul herauslösen (IN ARBEIT)
- 5.1 (
55050a1): Modul-Modelle (TrackedTrader, TraderAnalyticsResult, MasterTraderHistoryRecord) ins Modul verschoben. - 5.2 (
f8d395b): TradingState-Split — CoreTradingState(globale Schalter, Accounts, MarketCache, GlobalPnl) vs.CopyTradingStateim Modul (Traders, MasterTraderPositions, TraderAnalyticsCache, TotalCopyTrades, PendingOrderTimestamps, SixSharesMinimum); 10 Konsumenten umgestellt. Modulgrenze auf State-Ebene gezogen. - 5.3: Modul-Services physisch ins Modul-Projekt verschieben: TraderMonitorService, CopyTradingEngine, beide Analytics-Jobs. Ebenso die jetzt entkoppelbaren Infra-Services neu verorten: MarketSyncService (nur Core-State → Core), Alchemy/WSS/Snapshot (CopyTradingState-gekoppelt → Modul bzw. bleiben vorerst App).
- Copytrading-UI-Tabs aus
frm_mainin das Modul auslagern (Master/Slave-Verwaltung, Modul-Analyse, Closed Trades).frm_mainwird zur reinen Shell (Terminal, Jobs, Core-Gesamt-Dashboard, Settings-Rahmen). CopyTradingModule : IPolyTraderModuleimplementieren (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 (
tradersvs.trackers). - Ergebnis: Copytrading ist ein eigenständiges, entfernbares Modul.
Phase 6 — MySQL-Migration
- EF Core + Pomelo einrichten; relationales Schema modellieren
(u.a.
positionsmitaccount_idstatt Collection-per-Account;trader_accountsJoin-Tabelle fürAssignedAccountIds). - Zweite Repository-Implementierung (MySQL) hinter den bestehenden Interfaces.
- Einmaliges Migrationsskript Mongo → MySQL (agentspace/scripts).
- Umschalten per Konfiguration; Mongo/LiteDB/Shim +
data.dbentfernen.
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)
- Eigene Trading-Accounts → Core, kopierte Master-Trader → Copytrading-Modul.
- Zweistufiges Trade-Logging: generischer Core-Log (modulübergreifend) und zusätzlicher Copytrading-Detail-Log im Modul (siehe 2.4).
- ORM: Entity Framework Core.
- Dashboard: Core liefert Gesamt-Overview über alle Module; Module liefern eigene Detail-Analysen (siehe 2.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).