Files
IBKRTrader/docs/ARCHITECTURE.md
T
Richard 9effc43206 @
R6: Security - Master-Key + AES-256-GCM at-rest + TLS-Warnung

- Core/Security/SecretProtection: AES-256-GCM at-rest, Master-Key aus env IBKRTRADER_MASTER_KEY
  bzw. gitignorierte master.key; selbstheilendes enc:v1:-Format; Passthrough ohne Key (mit Warnung)
- Core/Security/EncryptedStringConverter (EF-ValueConverter, bereit fuer kuenftige Credentials)
- Program: ConfigureSecretProtection (Master-Key laden) + WarnIfDbTlsNotEnforced (SslMode) beim Start
- master.key gitignored
- Tests: SecretProtection (Round-Trip/Idempotenz/Passthrough/Tamper/Key-Fehler) -> 56/56 gruen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-28 19:53:21 +02:00

133 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IBKRTrader Architektur & Implementierungsplan
> **KORRIGIERT (2026-07-27):** Vorbild ist **PolytraderSharp** (`J:\Softwareprojekte\PolytraderSharp`),
> die C#-Neuentwicklung **nicht** die veraltete Python-Version. Die frühere Fassung dieses Plans
> basierte auf der Python-Vorlage und war konzeptionell falsch. Ziel ist eine **1:1-Neu-Fundamentierung**
> nach PolytraderSharp, im bestehenden IBKRTrader-Repo.
Ziel: modulares C#-Trading-Framework für Interactive-Brokers-Aktien, strukturell wie PolytraderSharp,
nur dass statt Polymarket über IBKR gehandelt wird.
---
## 1. Ziel-Architektur (nach PolytraderSharp)
```
IBKRTrader.App (WinExe, Root) Generic Host + Shell (Launcher) + Core-Views
│ Program.cs: Host.CreateDefaultBuilder, IConfiguration, Module laden, ShellUiHost, Application.Run
│ Ui/: LauncherForm, ShellUiHost, Views/ (Dashboard, Terminal, Settings, Jobs)
├── src/IBKRTrader.Core (classlib, net10.0-windows, UseWindowsForms)
│ ├── Modularity/ IModule (Name, DbPrefix, RegisterServices, RegisterUi, Start/Stop, ActivationBlocker)
│ │ ModuleView, IModuleUiHost, WindowMenu ← UI-Contract liegt im Core
│ ├── Configuration/ DatabaseOptions, ServerVersion-Pinning
│ ├── DependencyInjection/ AddCorePersistence(...)
│ ├── Persistence/Ef/ CoreDbContext + Entities + EF-Repositories (hinter Interfaces)
│ ├── Trading/ Broker-Seam, Risk, Execution, Portfolio, Domänentypen
│ ├── Services/ TerminalLogger, JobManager, Hosted Services (Market-Sync etc.)
│ ├── Security/ SecretProtection (Master-Key, AES-256-GCM at-rest)
│ └── Hosting/ StartupHydrationService (IHostedService, hydriert State zuerst)
├── src/IBKRTrader.Modules.CongressTrading (classlib, referenziert NUR Core)
│ ├── CongressTradingModule : IModule
│ ├── Persistence/Ef/ eigener DbContext (ct_) + Repos
│ ├── Services/ Scraper + Jobs (IHostedService)
│ └── Ui/ CongressTradingMainForm (Tabs) via RegisterUi
└── tests/IBKRTrader.Tests (xUnit, referenziert Core + Module)
```
### Leitprinzipien (aus PolytraderSharp übernommen)
- **Multi-Projekt**: Core = eigenes Assembly; jedes Modul = eigenes Projekt, referenziert **nur** Core.
Module können einander physisch nicht referenzieren.
- **Generic Host**: `Host.CreateDefaultBuilder`, `IHostedService` für alle Hintergrund-Jobs,
`IOptions`/`IConfiguration`.
- **Config**: `appsettings.json` + `appsettings.Local.json` (gitignored, hält Connection-String/Secrets).
- **Modul-Vertrag** `IModule`: `Name`, `DbPrefix`, `RegisterServices(services, config)`,
`RegisterUi(host, sp)`, `StartAsync/StopAsync`, `GetActivationBlocker(config)`.
- **UI = Shell + Views**: Core und Module registrieren `ModuleView`s beim `IModuleUiHost`.
Der Launcher öffnet je View ein Fenster (Einzelinstanz, Re-Open fokussiert). Gemeinsames
„Fenster"-Menü (`WindowMenu`) auf jedem Form. Views sind designbare Forms mit `Initialize(sp)`.
- **Persistenz**: EF Core (Pomelo/MySQL), `AddDbContextFactory`, Repositories hinter Interfaces.
- **Sicherheit**: Master-Key + AES-256-GCM-Verschlüsselung von Credentials at-rest; TLS-Warnung.
- **Headless-Test**: `--smoke-ui` konstruiert jede View + Launcher ohne Message-Loop.
- **Module an/aus** über `ServerSettings.DisabledModules`.
---
## 2. Was aus dem bisherigen Stand übernommen wird
| Bestand (Phase 03, Python-basiert) | Schicksal |
|---|---|
| Testprojekt (xUnit) | bleibt, wandert nach `tests/` |
| `RiskService`, `ExecutionService`, Domänentypen | Logik bleibt → Core/Trading (Feinschliff) |
| CongressTrading Scraper/Repo | Inhalt bleibt → eigenes Modul-Projekt (auf EF/IHostedService umgestellt) |
| `IModule`/`ModuleRegistry`/`WindowManager` | ersetzt durch PolytraderSharp-Contract (`IModule` neu, `ModuleView`, `IModuleUiHost`, `WindowMenu`) |
| Manuelles `ServiceCollection` in Program.cs | ersetzt durch Generic Host |
| `settings.json`/`SettingsService` | ersetzt durch `IConfiguration` + `appsettings.Local.json` |
| Dapper + manuelle Migrationen | ersetzt durch EF Core |
| `WorkerEngine`/`IWorker` | ersetzt durch `IHostedService` |
---
## 3. Re-Fundamentierungs-Phasen (Checkliste)
### R1 Solution-Skelett (Multi-Projekt, reiner Strukturumbau, Verhalten unverändert) ✅
- [x] `src/IBKRTrader.Core` (classlib, UseWindowsForms) `Core/` + UI-Contract (`Ui/ModuleFormBase`, `Ui/WindowManager`)
- [x] `src/IBKRTrader.Modules.CongressTrading` (classlib, referenziert nur Core)
- [x] Root-Projekt → `IBKRTrader.App` (WinExe), referenziert Core + Modul; Program/LauncherForm/UI-Shell bleiben
- [x] `tests/IBKRTrader.Tests` Referenzen auf Core + Modul; Fixture-Pfad angepasst
- [x] Neue `.slnx`; ungenutztes HtmlAgilityPack entfernt; Build + **38/38 Tests grün**; App startet
### R2 Core-Contracts + Generic Host + Shell-UI ✅
- [x] `IModule` (PolytraderSharp-Stil) + `ModuleView` + `IModuleUiHost` + `WindowMenu` in Core
- [x] `Program.cs``Host.CreateDefaultBuilder`; `IConfiguration` (appsettings.json + appsettings.Local.json, gitignored)
- [x] `ShellUiHost` + `LauncherForm` (View-Buttons + gemeinsames Fenster-Menü); Core-Views (Workers/Logs/Settings) als eigene Fenster
- [x] CongressTrading auf neuen `IModule`-Vertrag; Modul-Worker als `IWorker` registriert
- [x] `--smoke-ui` Headless-Test (alle Views + Launcher konstruieren) → grün
- [ ] **Offen (R4/R5):** Worker von `WorkerEngine`/`IWorker` auf `IHostedService` umstellen (aktuell noch WorkerEngine)
### R3 Persistenz auf EF Core
**Festgelegt:** EF-Migrationen **extern** (wie PolytraderSharp) Schema per `dotnet ef database update`,
App legt keine Tabellen zur Laufzeit an. Server: **MariaDB 11.8.6** (via `--db-version` bestätigt) →
Pin `new MariaDbServerVersion(new Version(11, 8, 6))`. Verbindung aus `appsettings.Local.json`.
- [x] `--db-version`-Diagnose (Serverversion für den EF-Pin)
- [x] **Slice 1:** `Configuration/DatabaseOptions` + `DatabaseServerVersion`-Pin (MariaDB 11.8.6); `AddCorePersistence` (`AddDbContextFactory`) + `CoreDbContext` + Entities (core_position, core_trade_history, core_budget, core_worker_log, core_settings) + Design-Time-Factory; **EF-Migration `InitialCore` erzeugt**
- [x] **Slice 2:** `PortfolioService`, `BudgetService`, `TradeHistoryService` auf EF (`IDbContextFactory<CoreDbContext>`) umgestellt; **5 EF-InMemory-Unit-Tests** (Buchführung real verifiziert). WorkerBase-Log folgt in Slice 4.
- [x] **Slice 3:** Modul auf EF (`CongressTradingDbContext` ct_ + `CongressRepository`); `WorkerBase`-Log auf EF (core_worker_log); `CoreSettingsService` (core_settings); `CoreMigrations`/`CongressMigrations` (Dapper) entfernt; EF-Migration `InitialCongressTrading`; `appsettings.Local.json` (gitignored) als Connection-Quelle; Fallback für leeren Connection-String. **+4 EF-InMemory-Tests** (CongressRepository)
- [x] **Slice 4:** IBKR-Marktdaten (`core_ibkr_*`) auf EF (3 Entities im `CoreDbContext`, Cross-Modul-Query via Raw-SQL); Migration `AddIbkr`; **Dapper + `DatabaseService` + `IBKRMigrations` vollständig entfernt** Persistenz ist jetzt **komplett EF Core**. +4 EF-InMemory-Tests.
**R3 abgeschlossen** gesamte Persistenz auf EF Core (Migrationen: `InitialCore`, `AddIbkr`, `InitialCongressTrading`), extern via `dotnet ef database update` anzuwenden.
- Hinweis: nur build-verifizierbar (Unit-Tests ohne DB); Schema-Anwendung extern via `dotnet ef database update` (env `IBKRTRADER_MYSQL`)
### R4 Worker auf `IHostedService` ✅
- [x] `WorkerBase` implementiert `IHostedService`; `IWorker` auf Metadaten+Trigger reduziert
- [x] Worker via `AddHostedService` registriert; Lebenszyklus über `AppHost.Start()`/`StopAsync()`
- [x] `WorkerEngine` auf leichte Registry reduziert (WorkerInfos für UI + `TriggerWorkerAsync`)
- [x] `LauncherForm` startet/stoppt keine Worker mehr; Build + 43/43 Tests + smoke-ui + App-Start grün
- Hinweis: Trading-Kern (Risk/Execution/Portfolio/Broker) wurde bereits in Phase 3 gebaut und in R3 auf EF gehoben
### R5 CongressTrading als vollständige Strategie ✅
- [x] `CongressTradingStrategy`: neuer Scrape-Trade → `TradeSignal` (buy/sell-Mapping) → Core-`IExecutionService`
- [x] `CongressScrapeWorker` ruft die Strategie je neuem Trade auf (per try/catch isoliert)
- [x] Modul-Fenster zeigt offene Positionen (`IPortfolioService.GetPositionsAsync("CT")`)
- [x] **8 neue Tests** (Signal-Mapping/Ausführung, gemockter ExecutionService) → 51/51 grün
- Hinweis: Handel bleibt durch Trading-Gate (`TradingEnabled=false`) + `NullBrokerClient` sicher aus, bis echter Broker + Freigabe
### R6 Sicherheit + Config-Härtung ✅
- [x] `SecretProtection` (Master-Key aus env `IBKRTRADER_MASTER_KEY`/`master.key`, AES-256-GCM at-rest, selbstheilendes `enc:v1:`-Format) + `EncryptedStringConverter` (bereit für künftige IBKR-Credentials)
- [x] `ConfigureSecretProtection` + TLS-Warnung (`SslMode`) beim Start; `master.key` gitignored
- [x] Connection-String in `appsettings.Local.json` (gitignored)
- [x] **5 SecretProtection-Tests** (Round-Trip, Idempotenz, Passthrough, Tamper/Key-Fehler) → 56/56 grün
- [ ] **Offen (Nutzer-Aktion):** geleaktes DB-Passwort rotieren (liegt in Git-Historie via `grundregeln.md`, Commit `ebeb035`); EF-Schema per `dotnet ef database update` auf die DB anwenden
### R7 Tests + Feinschliff
- [ ] Bestehende Unit-Tests portieren; `--smoke-ui`; EF-InMemory-Tests wo sinnvoll
---
## 4. Historie (bereits erledigt, teils zu ersetzen)
- Phase 03 (Python-basiert): Testfundament, IModule/ModuleRegistry, LauncherForm+WindowManager,
Trading-Kern (Risk/Execution/Portfolio, NullBroker). Logik brauchbar, Infrastruktur wird ersetzt.
- Commits bis `2ad4b55` auf Gitea.