- TraderMonitorService las API-Preise kulturabhaengig: unter de-DE wurde aus
"0.53" der Wert 53 (Faktor-100-Fehler im Einstandspreis). Nutzt jetzt den
bereits vorhandenen invarianten Helper ParseDecimal.
- Gleiche Fehlerklasse in PolymarketClobClient (6x) und MasterTraderAnalyticsJob
vorsorglich auf InvariantCulture gestellt.
- Neuer Regressionstest ApiNumberParsingTests (10 Faelle unter erzwungener de-DE-Kultur).
- Threema komplett entfernt (Entscheidung Richard): ThreemaService, vendorte
Bibliothek libs/Threema-MsgApi-Net-Core, ServerSettings-Block, DI-Verdrahtung.
- Ersetzt durch neutrale INotificationSink (No-Throw-Vertrag) + LogNotificationSink
als Uebergang; RocketChat/Telegram folgen spaeter.
- Entfernt nebenbei libsodium 1.0.16, die einzige Registry-Nutzung im Build,
den HttpListener-Webhook und System.Web.HttpUtility (alles Linux-Hindernisse).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Slices W-A/W-B/W-C und L-A aus UMSETZUNGSPLAN-Watchdog-LicenseLabrador-Integration.
Watchdog (Dead-Man's-Switch, externer Server):
- WatchdogHeartbeatService als BackgroundService + DI-Singleton; jeder Sendeversuch
gekapselt, ein Ausfall des Watchdogs beeintraechtigt PolyTrader nie.
- Eigene Implementierung statt Test-Client des Fremdprojekts: TLS-Pruefung bleibt
aktiv, http:// nur fuer localhost (Agent-Token nicht im Klartext ins Netz).
- Status aus dem App-Log abgeleitet (Error mit 5-Minuten-Sticky-Fenster, entprellt),
Lifecycle-Events started/stopping.
- Konfiguration in ServerSettings; Agent-Token [Browsable(false)] mit maskierter
Eingabe + Statusanzeige, bei gesetztem Master-Key verschluesselt (enc:v1:).
Lizenz (LicenseLabrador, Ed25519):
- LicenseGate.RunStartupGate prueft beim Start; bei ungueltiger Lizenz wird die
Modulliste leer gebaut, sodass nur die Core-Shell (Terminal/Einstellungen)
startet. Bewusst kein Environment.Exit - ein Trading-Bot darf nicht mitten im
Lauf hart sterben. TamperSuspected gilt als nicht nutzbar.
- LicenseDialog (partial + .Designer.cs) fuer Start- und Verwalten-Modus, mit
Hardware-ID zum Kopieren; Smoke-UI konstruiert beide Modi headless.
- Master-Key wird jetzt VOR dem Host-Build geladen, da auch der Lizenzschluessel
entschluesselt werden muss; derselbe TerminalLogger wird als Singleton
weitergereicht, damit die Startmeldungen im Terminal-Fenster erscheinen.
Der Lizenz-SDK-Client wird per Cross-Repo-Projektreferenz auf
..\..\LicenseLabrador eingebunden, damit SDK-Fixes ohne Kopie einfliessen.
484 Zeilen Tests fuer den Heartbeat; Suite gruen (438 Tests).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Fenster-Menue: WindowMenu fuellt die oberste MenuStrip mit Top-Level-Eintraegen
nebeneinander (mit Icon) statt Untermenue "Fenster"; ModuleView.Icon zentral in der
App zugewiesen (AssignMenuIcons). Kein miFenster mehr im Launcher-Designer.
- Sicheres Beenden: ShutdownConfirmDialog (10s-Timer sperrt "Jetzt beenden", Abbrechen
jederzeit) via IModuleUiHost.RequestShutdown(). Nur der Launcher (Hauptprozess) bietet
"Beenden"; andere Fenster nur "Fenster schliessen" (kein App-Shutdown, Module laufen
weiter). Launcher-Schliessen-X routet ueber dieselbe Abfrage.
- Modul-Aktivierung (restart-basiert): ServerSettings.DisabledModules, in Program.Main
vor der DI-Registrierung gefiltert -> deaktivierte Module werden nicht geladen.
Dashboard-Tab "Module" zeigt Status + schaltet um (Hinweis: greift nach Neustart).
Optionaler IPolyTraderModule.GetActivationBlocker fuer "nicht aktivierbar"-Info.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Das Dashboard ist keine stumpfe Trade-Liste mehr, sondern ein Auswertungs-Fenster:
- ToolStrip (via Designer): Scope-Filter Konto/Modul/Live-Demo/Zeitraum + Aktualisieren.
- TabControl mit 2 Tabs:
- Dashboard: KPI-Kacheln (Netto-PnL/Winrate/Trades/O-PnL/Profit-Faktor) + 3 Charts
(Equity-Kurve, PnL je Modul, PnL je Tag) fuer den gewaehlten Scope.
- Tradehistorie: gefilterte Trade-Liste (Spalten via Designer) + Suche + Gewinner/Verlierer.
- Charts via ScottPlot CORE-Paket (nur SkiaSharp, .NET-nativ) -> als Bitmap in PictureBoxen
gerendert; KEINE OpenTK/.NET-Framework-Transitiven (bewusst nicht ScottPlot.WinForms).
- Auswertungslogik pur in TradeAnalytics (getestet). In-Memory-Filter auf gecachtem Recent-Set.
- Smoke-UI konstruiert die DashboardView jetzt direkt -> verifiziert das Chart-Rendering headless.
Build 0 Fehler, 331 Tests gruen, --smoke-ui: [OK] core.dashboard konstruiert (inkl. Charts).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- F5: Startwarnung, wenn der DB-Connection-String kein SslMode erzwingt (String selbst wird
nie geloggt). Eure Connection enthaelt bereits SslMode -> Warnung bleibt aus.
- F6: geprueft - keine Secret-Werte in Logs (nur Vorhandensein-Flags/Fehlermeldungen).
- Sicherheitskonzept: Status F1-F7 dokumentiert.
Build 0 Fehler, --smoke-ui ok.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Behebt den kritischsten Befund (Klartext-Private-Keys in remote-gehosteter MySQL):
- SecretProtection (Core/Security): AES-256-GCM, authenticated. Master-Key AUSSERHALB der DB
(env POLYTRADER_MASTER_KEY, sonst gitignorierte master.key). Format enc:v1:base64(nonce|tag|ct).
Alt-Klartext (ohne Praefix) wird gelesen und beim Speichern verschluesselt (selbstheilend).
Ohne Master-Key: Passthrough + deutliche Startwarnung (kein stiller Sicherheitsverlust).
- EncryptedStringConverter (EF ValueConverter) auf core_accounts.PrivateKey/ApiSecret/ApiPassphrase;
Spalten 256->512 verbreitert (Migration EncryptAccountSecretsWidenColumns, offline generiert).
- Program.cs: Master-Key vor der Hydration laden; nach Start einmalige/idempotente Re-Encryption
vorhandener Klartext-Credentials. Auch in --smoke-ui verdrahtet.
- CoreDbContextFactory nutzt jetzt fixe Server-Version (offline-Migrationsgenerierung, kein DB-Zugriff).
13 neue Krypto-Tests (Round-Trip, Nonce-Frische, Manipulations-/Falscher-Key-Erkennung, Passthrough,
Key-Formate). Build 0 Fehler, 324 Tests gruen, --smoke-ui ok (Warnung ohne Key wie erwartet).
AKTIVIERUNG (im Zielland): POLYTRADER_MASTER_KEY setzen (zufaelliger 32-Byte-Base64-Key, SEPARAT sichern!)
+ Migration anwenden (dotnet ef database update --context CoreDbContext). Danach Alchemy-/Mullvad-Secrets
aus F3 rotieren. WICHTIG: Master-Key-Verlust = Kein Zugriff auf die Keys mehr.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
H4 – Rundungs-Dust-Reject-Schleife:
- SellLogic.RoundToTick (0.001, AwayFromZero, wie CalculateExactOrderAmounts). Die
Leiter platziert Preise gerundet -> usdc = size × Preis geht exakt auf (kein Dust).
- ProcessLadderAsync bricht ab, wenn pos.Size < MinShares (Dust-Rest gehalten,
ExitPending=false), statt endlos Sub-Minimum-Orders zu schicken.
M1 – GlobalPnl-Doppelzaehlung: in beiden Live-Close-Bloecken jetzt NUR innerhalb des
_processedClosures-Dedup-Guards gebucht (API-Lag zaehlte sonst doppelt).
M2 – TokenId in beiden Live-Close-Records gesetzt (sonst greift die Dedup nach Neustart nicht).
M3 (Minimum) – TradeId-Init: serverseitiges GetMaxTradeId() statt Full-Table-Find(_=>true).Max();
Fehlschlag wird laut geloggt statt still geschluckt. (Autoincrement-Migration bewusst als
Follow-up aufgeschoben – Schema-Aenderung an der Trade-Persistenz erst im Zielland live verifizieren.)
M4 – MongoExportParser ProfitTarget-Default 50 -> 9999 (Take-Profit bleibt dormant).
M6 – Fee-Satz (real oder Kategorie-Fallback, FeeModel.ResolveBps) in alle signierten Orders:
Engine-BUY, SELL-Leiter (Start/Step/Floor), PreRedeem (WSS + REST). API-gated, im Zielland verifizieren.
Doku – stale [Description]: ProfitTarget/SellFloorPct als IMPLEMENTIERT markiert.
Tests: +10 (RoundToTick, Dust-Abbruch, ResolveBps). Build 0 Fehler, 233 gruen, --smoke-ui ok.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MasterTraderAnalyticsJob + PersistenceService von services/ nach
src/PolyTrader.Modules.CopyTrading/Services/ verschoben und in
CopyTradingModule.RegisterServices registriert (reiner Move). Beide sind
copytrading-spezifisch (Master-Trader-Historie bzw. Persistenz der
geschlossenen Copytrades ueber den Modul-Channel; Dual-Write in Core-Log bleibt).
- Program.cs: die zwei Hosted-Service-Registrierungen entfernt.
- appsettings.json: Logging-Sektion ergaenzt -> EF-Core-Command-Logging auf
Warning (kein SQL-Spam mehr; --smoke-ui zeigt 0 "Executed DbCommand"-Zeilen).
Damit liegt die gesamte Copytrading-Logik im Modul; App/Core enthalten nur noch
generische Infrastruktur + Startup-Hydration + CLI-Tools.
Build gruen, 48 Tests gruen, --smoke-ui gruen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beide Listener sind copytrading-spezifisch (überwachen die getrackten Master-
Trader bzw. Auto-Redeem nach Copytrading-Settings) und werden jetzt vom Modul
besessen statt von der App. Reiner Move, keine Logikänderung.
- services/AlchemyWebsocketService.cs + services/PolymarketWssClient.cs
-> src/PolyTrader.Modules.CopyTrading/Services/ (Namespace bleibt transitional).
- CopyTradingModule.RegisterServices registriert nun beide Hosted Services sowie
IBlockchainWssClientFactory->AlchemyWssClientFactory (Core-WSS-Infra, nur vom
Copytrading-Blockchain-Listener genutzt).
- Program.cs: die drei Registrierungen entfernt (WSS-Factory + 2 Hosted Services)
+ ungenutztes using PolyTrader.Core.Streaming.
- WSS-Verbindungsinfrastruktur (AlchemyWssClient/BlockchainWss) bleibt in Core.
DI-Auflösung unverändert (gleicher Container). Build grün, --smoke-ui grün.
Laufzeit-Verifikation der WSS-Verbindungen: Server-Test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ursachen (App startete aus bin/ bzw. per Doppelklick ohne UI):
1. appsettings.Local.json (MySQL-Connection) wurde NICHT ins Output kopiert und
nur relativ zum Arbeitsverzeichnis geladen -> leere Connection -> Pomelo fiel
auf localhost:3306 zurueck -> "Connect Timeout expired".
2. ServerVersion.AutoDetect(conn) oeffnet beim Options-Bau eine blockierende
DB-Verbindung -> haengt/crasht den Start, wenn die DB nicht erreichbar ist.
3. CopyTradingEngine.StartAsync lud den MarketCache ungeschuetzt -> DB-Fehler
riss AppHost.Start() ab, bevor die UI erschien.
Fixes:
- csproj: appsettings.Local.json mit ins Output kopieren (CopyToOutputDirectory).
- Program: UseContentRoot(AppContext.BaseDirectory) -> Config wird immer neben
der EXE gesucht (Main + Smoke-Test).
- ServerVersion fest gepinnt: DatabaseServerVersion.Value = MariaDB 11.8.6 (wie
am Server erkannt); AddCorePersistence + CopyTradingModule nutzen sie statt
AutoDetect. Kein blockierender Connect mehr beim Start.
- CopyTradingEngine-Preload in try/catch: DB-Fehler bricht den Start nicht mehr ab.
- Neuer Diagnose-CLI --db-version (gibt @@version aus).
Verifiziert: --smoke-ui aus fremdem Arbeitsverzeichnis laeuft gruen
(3 Accounts / 32 Trader hydriert, alle Views + Launcher OK).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- KRITISCH: Host.CreateDefaultBuilder lädt appsettings.Local.json nicht (nur
appsettings.json + appsettings.{Environment}.json). Dadurch war
Database:MySqlConnectionString zur Laufzeit leer -> Pomelo fiel auf
localhost:3306 zurück ("Connect Timeout expired"), die GUI-App hätte am
Server nie mit MySQL verbunden. Fix: appsettings.Local.json explizit per
ConfigureAppConfiguration ergänzen (in Main und im Smoke-Test).
- Neuer CLI-Modus --smoke-ui: baut einen minimalen Host, hydriert den State
aus MySQL und konstruiert jede registrierte View + den Launcher (ohne
Message-Loop / Trading-Services). Deckte den obigen Bug auf.
- Verifiziert: 3 Accounts / 32 Trader hydriert; alle 3 Modul-Views + Launcher
konstruieren fehlerfrei mit echten Daten.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ConfigMigrator: kopiert Accounts, aktive Markets, Master-Trader,
Copytrading-Settings (mit Fallback auf Alt-Felder im accounts-Dokument)
und Demo-Positionen; Historie startet leer. Idempotent via Upserts.
- Getrennte Mini-Container fuer Quelle (Mongo) und Ziel (EF/MySQL),
unabhaengig vom Provider-Toggle.
- Aufruf: PolyTrader.App --migrate-config (kein UI-Start).
- Erstlauf: 2344 Markets migriert; Accounts/Trader/Settings in lokaler
Mongo leer (nichts zu migrieren).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ModuleView liefert jetzt ein Form (CreateForm statt CreateControl); die 4 Views
(Terminal, Settings, Jobs, Dashboard) von UserControl auf Form umgestellt
(im Designer als Fenster bearbeitbar). ViewHostForm entfernt.
- ShellUiHost verwaltet offene Forms: Einzelinstanz, bereits offenes Fenster wird
in den Vordergrund geholt, OpenStateChanged-Event.
- LauncherForm: Fenster-Buttons an View-IDs gebunden; offene Fenster werden am
Button markiert (Checked), erneuter Klick holt das Fenster nach vorn.
- Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- TraderMonitorService, CopyTradingEngine, TraderAnalyticsJob physisch ins
Modul-Projekt (src/PolyTrader.Modules.CopyTrading/Services) verschoben.
- Neu: CopyTradingModule : IPolyTraderModule — registriert CopyTradingState,
die Signal-/Trade-Channels, ICopyTradeLogRepository und die Modul-Services selbst.
- Program.cs: Modul-Discovery (foreach module.RegisterServices / RegisterUi);
die entsprechenden Direkt-Registrierungen entfernt. StartupHydration laeuft
weiterhin als erster HostedService (State-Hydration vor Trading).
- MasterTraderAnalyticsJob bleibt vorerst in der App (nutzt noch den App-Shim
fuer mt_history -> braucht erst ein History-Repo). RegisterUi noch leer
(Modul-Views folgen; Copytrading-UI weiter ueber Legacy erreichbar).
- Build 0 Fehler. Launcher zeigt jetzt "Module: 1".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Core: TradeRecord (Modell) + ITradeLogRepository (+ Mongo-Impl, Collection
"trade_log"), in AddCorePersistence registriert. Realisiert den generischen,
modulneutralen Trade-Log aus Entscheidung #2.
- Dual-Write: PersistenceService schreibt geschlossene Copy-Trades zusaetzlich als
generischen TradeRecord (ModuleName="CopyTrading").
- Neue DashboardView (UserControl + Designer): zeigt die letzten Trades ALLER
Module (GetRecent) mit Konto-Aufloesung + Kurzauswertung (Gesamt-PnL, Anzahl,
Aufschluesselung je Modul). btn_dashboard im Launcher, View "core.dashboard".
- Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Neue JobsView (UserControl + Designer): DataGridView an JobManager.Jobs,
Run-Now/Aktiv-Verhalten wie bisheriger Jobs-Tab. btn_jobs in toolstrip_windows,
als View "core.jobs" registriert.
- Trading-Toggle aus frm_main uebernommen: btn_liveTrading + btn_demoTrading in
toolstrip_quickbar; Zyklus Inactive->SellOnly->Active mit Farb-/Textstatus,
synchron zum TradingState (auch bei externen Aenderungen via 1s-Timer).
- Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ClosedTrade (+ ClosedTradeRow) nach src/PolyTrader.Modules.CopyTrading/Models/.
- Neues ICopyTradeLogRepository (+ Mongo-Impl) im Modul: EnsureIndexes, Exists,
Insert, Find(predicate) auf der closed_trades-Collection.
- closed_trades-Zugriffe der Modul-Services vom App-Shim auf das Repo umgestellt:
TraderMonitorService, PersistenceService, PolymarketWssClient, TraderAnalyticsJob.
Shim-/DB-Usings dort entfernt.
- TraderMonitorService nutzt kein _db mehr (auch die uebrigen _db-Guards aus 3d
entfernt, da Repos immer verfuegbar sind). Verhaltensneutral.
- frm_main (UI) + Program.cs (BsonDocument-Cleanup) bleiben auf _db.
- Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Neuer StartupHydrationService (IHostedService), als ERSTER HostedService
registriert: hydriert Accounts (+ Demo-Positionen via Repos) und Trader
(trackers-Collection) in den TradingState, bevor die Trading-Services
ihre ExecuteAsync starten.
- frm_main.LoadDatabaseAndState() + beide Aufrufe entfernt (verhinderte
doppelte, überschreibende Hydration nach Service-Start).
- Behebt den Race, bei dem Services gegen leeren State anliefen.
- Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Interfaces: IAccountRepository, IMarketRepository, IPositionRepository
(IPositionRepository kapselt das Collection-per-Account-Muster).
- Mongo-Implementierungen bilden die bisherige Shim-Semantik 1:1 mit direkten
MongoDB.Driver-Aufrufen nach (kein App-Shim-Bezug im Core).
- AddCorePersistence()-Erweiterung + Registrierung in Program.cs.
- Noch keine Call-Sites umgestellt; Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Neue Core-Klasse DatabaseOptions (Sektion "Database"), gebunden via IOptions.
- appsettings.json im App-Projekt (Mongo-Connection + DB-Name), wird in den
Output kopiert.
- Program.cs: hart codierte "mongodb://localhost:27017" und "PolyTraderDB"
durch konfigurierte Werte ersetzt.
- Startup-Cleanup-Hack aus dem Kopf von Main() entfernt und gekapselt nach
dem Host-Build über die konfigurierte DB neu verankert.
- Solution-Build 0 Fehler; appsettings.json im Output verifiziert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>