Files
IBKRTrader/docs/ARCHITECTURE.md
T
RichardandClaude Opus 5 9f66183f1c
Build & Test / build (ubuntu-latest) (push) Waiting to run
Build & Test / build (windows-latest) (push) Waiting to run
Eine Roadmap statt sieben Konzepte; Quelldokumente ins Archiv
Der offene Stand lag ueber sieben Konzepte, zwei Referenzdokumente und die
Phasen-Checkliste der Architektur verteilt. Dieselbe Aufgabe stand teils
doppelt unter zwei Namen - die asynchrone Fill-Verfolgung etwa als "bekannte
Grenze" in IBKR-Integration.md und zugleich als W-2 im OptionsWheel-Konzept.
Wer wissen wollte, was als Naechstes ansteht, musste alles neun lesen.

docs/ROADMAP.md fuehrt das zusammen:
  - Fuenf Stufen in Abhaengigkeitsreihenfolge, von "Fundament schliessen" bis
    zum OptionsWheel, dazu vier laufende Bahnen (Auslieferung, Accounting,
    Supervisor, technische Schulden).
  - Jede Zeile traegt ihre Herkunft (W-2, P5, Kapitalmodell 5, ...), damit die
    Herleitung im Archiv auffindbar bleibt.
  - Eigene Abschnitte fuer Zurueckgestelltes und Verworfenes. Zurueckgestellte
    Ideen nennen ausdruecklich, WAS sie wieder aktuell macht; verworfene nennen
    den Grund, damit sie nicht in sechs Monaten erneut vorgeschlagen werden.
  - Erledigtes bleibt als Zeile mit Datum stehen statt zu verschwinden.

Archiv (git erkennt alle sieben als Umbenennung, Historie bleibt):
  docs/konzepte/*         -> docs/archiv/
  docs/Kapital-und-Buchmodell.md -> docs/archiv/
Jedes archivierte Dokument bekommt oben einen Vermerk, warum es erhalten bleibt
und wo der lebende Stand steht. Inhaltlich ist keines veraendert.

Weiter gepflegt werden ARCHITECTURE.md (Aufbau + Phasen-Historie),
IBKR-Integration.md (Adapter-Design und Grenzen) und die TWS-Setup-Checkliste -
das sind Referenzen, keine Planung. Ihre eigenen Offen-Listen verweisen jetzt
mit Roadmap-Kennung dorthin, statt einen zweiten Stand zu fuehren.

Alle 63 relativen Markdown-Links geprueft, keiner tot. Fuenf Pfadverweise in
Code, csproj und systemd-Unit mitgezogen; die Unit zeigte auf die
Portierungsanalyse, die ausdruecklich den Stand VOR dem Umbau beschreibt - jetzt
auf ARCHITECTURE.md. Build 0 Warnungen, 198/198 Tests gruen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 18:14:51 +02:00

18 KiB
Raw Blame History

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.

Was dieses Dokument ist und was nicht. Abschnitt 1 beschreibt den heutigen Aufbau und ist die lebende Architektur-Referenz. Abschnitt 3 ist die Historie: die Phasen-Checklisten, an denen nachlesbar ist, was wann und warum gebaut wurde. Beides bleibt gepflegt.

Der offene Stand steht seit dem 2026-08-23 nicht mehr hier, sondern in der Roadmap. Die wenigen offenen Kästchen unten sind mit ihrer Roadmap-Kennung versehen, damit die beiden Listen nicht auseinanderlaufen. Neue Aufgaben gehören ausschließlich in die Roadmap.


1. Ziel-Architektur (nach PolytraderSharp)

Stand seit der Linux-Portierung (2026-08-07): Alle Projekte sind net10.0 ohne Plattformbindung. Die WinForms-Shell ist entfernt; der letzte Stand liegt im Tag winforms-final. Einstiegspunkte sind jetzt IBKRTrader.App (mit Oberfläche) und IBKRTrader.Daemon (kopflos, systemd); beide bauen ihren Host über IBKRTrader.Hosting. Analyse und Vorgehen: archiv/KONZEPT-Linux-Portierung.md.

src/IBKRTrader.App            (WinExe, net10.0)  Oberfläche: Launcher, Shell, Core-Views, Modul-Fenster
│   Program.cs: Host bauen (Hosting), Startprüfungen, dann Avalonia; --smoke-ui ohne Anzeigegerät
│   Shell/: AvaloniaUiHost, CoreViews, ModuleViews, ViewIcons, WindowMenu
│   Views/: LauncherWindow, Dashboard/Workers/Logs/Settings, Views/Modules/ (3 Modul-Fenster)
│
src/IBKRTrader.Daemon         (Exe, net10.0)  kopfloser Dienst: --check, --db-version, SIGTERM
src/IBKRTrader.Hosting        (classlib, net10.0)  AppHostBuilder + RunStartupChecks, von beiden geteilt
│
├── src/IBKRTrader.Core            (classlib, net10.0  plattformneutral, kein UI-Toolkit)
│   ├── Modularity/       IModule (Name, DbPrefix, RegisterServices, RegisterUi, Start/Stop, ActivationBlocker)
│   │                     ModuleView, IModuleUiHost   ← toolkit-neutraler UI-Contract (Func<object>, IconKey)
│   ├── Time/             AppTimeZone (Betriebszeitzone der Instanz; Persistenz bleibt UTC)
│   ├── 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)
│   └── (kein UI-Code  das Modul-Fenster liegt in der Shell, s. App/Shell/ModuleViews.cs)
│
└── 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: Der Core stellt den toolkit-neutralen Contract (ModuleView, IModuleUiHost), die Shell setzt ihn in Avalonia um. Der Launcher öffnet je View ein Fenster (Einzelinstanz, erneutes Öffnen fokussiert), jedes Fenster trägt das gemeinsame „Fenster"-Menü. Layout deklarativ in .axaml; Module tragen keinen UI-Code.
  • 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)

  • src/IBKRTrader.Core (classlib, UseWindowsForms) Core/ + UI-Contract (Ui/ModuleFormBase, Ui/WindowManager)
  • src/IBKRTrader.Modules.CongressTrading (classlib, referenziert nur Core)
  • Root-Projekt → IBKRTrader.App (WinExe), referenziert Core + Modul; Program/LauncherForm/UI-Shell bleiben
  • tests/IBKRTrader.Tests Referenzen auf Core + Modul; Fixture-Pfad angepasst
  • Neue .slnx; ungenutztes HtmlAgilityPack entfernt; Build + 38/38 Tests grün; App startet

R2 Core-Contracts + Generic Host + Shell-UI

  • IModule (PolytraderSharp-Stil) + ModuleView + IModuleUiHost + WindowMenu in Core
  • Program.csHost.CreateDefaultBuilder; IConfiguration (appsettings.json + appsettings.Local.json, gitignored)
  • ShellUiHost + LauncherForm (View-Buttons + gemeinsames Fenster-Menü); Core-Views (Workers/Logs/Settings) als eigene Fenster
  • CongressTrading auf neuen IModule-Vertrag; Modul-Worker als IWorker registriert
  • --smoke-ui Headless-Test (alle Views + Launcher konstruieren) → grün
  • Worker von WorkerEngine/IWorker auf IHostedService umgestellt — in R4 erledigt, die Zeile stand hier bis zum 2026-08-23 faelschlich noch offen

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.

  • --db-version-Diagnose (Serverversion für den EF-Pin)
  • 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
  • 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.
  • 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)
  • 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

  • WorkerBase implementiert IHostedService; IWorker auf Metadaten+Trigger reduziert
  • Worker via AddHostedService registriert; Lebenszyklus über AppHost.Start()/StopAsync()
  • WorkerEngine auf leichte Registry reduziert (WorkerInfos für UI + TriggerWorkerAsync)
  • 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

  • CongressTradingStrategy: neuer Scrape-Trade → TradeSignal (buy/sell-Mapping) → Core-IExecutionService
  • CongressScrapeWorker ruft die Strategie je neuem Trade auf (per try/catch isoliert)
  • Modul-Fenster zeigt offene Positionen (IPortfolioService.GetPositionsAsync("CT"))
  • 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

  • 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)
  • ConfigureSecretProtection + TLS-Warnung (SslMode) beim Start; master.key gitignored
  • Connection-String in appsettings.Local.json (gitignored)
  • 5 SecretProtection-Tests (Round-Trip, Idempotenz, Passthrough, Tamper/Key-Fehler) → 56/56 grün
  • Offen → Roadmap B1 / B3: 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 Feinschliff

  • Core-Dashboard-View (Gesamtüberblick: Trading-Modus, aggregierte Kennzahlen, geladene Module) + Icon
  • DashboardService (aggregiert Positionen/Exposure/Trades via EF) + 2 InMemory-Tests → 58/58 grün
  • Tests durchgehend portiert; --smoke-ui deckt alle Views ab
  • Echter IbkrBrokerClient über die TWS API (2026-07-31): src/IBKRTrader.Core/Trading/Ibkr/ IbkrMapping (rein, unit-getestet), IbkrConnection (Socket + reqId-Korrelation), IbkrBrokerClient (IBrokerClient). Aktivierung über IBKRSettings.UseTwsApi; NullBrokerClient bleibt Default. Design und Grenzen: IBKR-Integration.md, Einstellungen: TWS-Setup-Checkliste.md.
  • Gegen Paper-Konto DUR371528 verifiziert: Verbindung, Konto (NetLiquidation 100.105,50 EUR), Kurse (AAPL/MSFT/NVDA, verzögert) und Fehlerpfade
  • Orderpfad bis zur Broker-Annahme per What-If-Order verifiziert (Aktie + Option, keine Ausführung); Optionsberechtigung im Paper-Konto bestätigt
  • IBrokerPortfolioReader (Bestand + Ausführungen beim Broker) eigener Seam neben IBrokerClient, Grundlage für den Abgleich der eigenen Buchführung; gegen DUR371528 verifiziert (2 Positionen, 2 Ausführungen inkl. Kommissionen)
  • Offen → Roadmap H1 / H2: PlaceOrderAsync mit echter Ausführung verifizieren (Fill → Buchung); asynchrone Fill-Verfolgung (Orders ohne sofortige Ausführung)
  • Offen → Roadmap H3: IBKR-Account-Credentials mit EncryptedStringConverter speichern

L0L5 Linux-Portierung: Avalonia statt WinForms (2026-08-07)

Analyse und Begründung: archiv/KONZEPT-Linux-Portierung.md. Rückfallpunkt für den letzten WinForms-Stand: Tag winforms-final.

  • L0 NuGet.config repariert drei Pakete hatten kein packageSourceMapping-Muster; ein frischer Klon konnte nicht wiederherstellen (auf dem Entwicklungsrechner unsichtbar, weil gecacht)
  • L1a Core und Module von WinForms entkoppelt: net10.0 statt net10.0-windows. UI-Contract toolkit-neutral (Func<object> CreateView, IconKey statt System.Drawing.Image letzteres ist seit .NET 7 Windows-only). LoggingService meldet über EntryWritten statt eine RichTextBox zu halten
  • L1b Betriebszeitzone (AppTimeZone, Trading.ApplicationTimeZoneId): EU- und US-Instanzen sauber getrennt, Persistenz bleibt UTC. ParseExecutionTime verwirft die von TWS gemeldete Börsenzeitzone nicht mehr, sondern rechnet gegen sie nach UTC. Kultur-Fixes (PDF-Beträge fest de-DE, Scraper-Datum TryParseExact), BackupWorker plattformunabhängig, DB-Passwort über MYSQL_PWD statt Kommandozeile
  • L2 Kopfloser Dienst IBKRTrader.Daemon (systemd, --check, --db-version) + IBKRTrader.Hosting als geteilte Host-Zusammenstellung. AppPaths (Umgebungsvariable → Binärverzeichnis wenn beschreibbar → FHS)
  • L3 Avalonia-Shell (11.3.19, DataGrid 11.3.13) + Core-Ansichten. PropertyGrid ersetzt durch eine aus den Attributen erzeugte Einstellungsmaske (11 Abschnitte, 41 Felder)
  • L4 Die drei Modul-Fenster portiert; CI-Matrix ubuntu + windows
  • L5 WinForms vollständig entfernt IBKRTrader.App, LauncherForm, UI/, Properties/Resources.*

Ergebnis: Alle Projekte net10.0 ohne Plattformbindung. publish -r linux-x64 liefert Daemon (11 MB) und Oberfläche (32 MB) ohne eine einzige Windows-Abhängigkeit. Der Smoke-UI-Lauf braucht kein Anzeigegerät mehr und ist damit erstmals Teil der CI.

Offen → Roadmap H4 / T3: IB Gateway kopflos betreiben (IBC + Xvfb) eigene Baustelle, unabhängig vom Code; LiveCharts2 kommt mit den neuen Modulen (Avalonia deshalb auf der 11er-Linie gepinnt).

L6 Namensgebung bereinigt (2026-08-07)

  • IBKRTrader.App.AvaloniaIBKRTrader.App. Das Suffix gab es nur, solange daneben eine WinForms-IBKRTrader.App stand; seit L5 ist die weg. Assembly, Wurzel-Namensraum und die avares://-Ressourcen-URI sind mitgezogen, Git erkennt alles als Umbenennung.
  • Die global::Avalonia-Qualifizierungen entfallen sie waren nur nötig, weil der Namensraum IBKRTrader.App.Avalonia das gleichnamige Paket verdeckte.
  • Inhaltlich falsch gewordene Aussagen berichtigt das waren die eigentlichen Überbleibsel, nicht die Kommentare: .agents/rules/grundregeln.md schrieb weiterhin „C# .NET 10 WinForms", RichTextBox-Logging, LauncherForm und PropertyGrid vor und hätte die Portierung Stück für Stück rückgängig gemacht. Dazu Core-Kommentare (LogEntry, IWorker, ModuleView) und Doku.

DC Deploymentcenter-Integration (2026-08-23)

Konzept und Begründung: archiv/KONZEPT-Deploymentcenter-Integration.md. Schritte 08 der dortigen Reihenfolge sind umgesetzt; der Stand je Schritt steht in §9 dieses Konzepts.

  • Lizenz (Sperrbetrieb statt Abbruch), Watchdog-Heartbeat, Fehler-Stream inkl. globaler Ausnahmebehandler, Update-Prüfung mit ReleaseCredentials, setup.json + Release-Pipeline. Einbauort ist IBKRTrader.Hosting/Deploymentcenter/ den Host teilen sich Shell und Daemon.
  • Vier Projekt-Befunde vorab bereinigt: Zugangsdaten aus AppSettings (P1), AppPaths-Rückfall unter Windows (P2), globale Handler (P3), Version zentral in Directory.Build.props (P4).
  • Offen (P5) → Roadmap D1: Die Gitea-CI checkt das Schwester-Repo Deploymentcenter nicht aus. Solange das SDK als Cross-Repo-ProjectReference hängt, ist der CI-Lauf rot. Behebt sich mit Schritt 10 (SDK als NuGet-Paket in der Gitea-Registry).
  • Offen (Schritt 9) → Roadmap D2 / D5: Bugtracker-Baustein setzt voraus, dass das Projekt ibkrtrader im DC-WebUI angelegt ist und ein Token mit bugtracker:report vorliegt (serverseitige Handarbeit).
  • Offen → Roadmap D3: Das Anwenden eines gefundenen Updates ist nicht verdrahtet. DcUpdateService.LaunchAgent ist fertig und dokumentiert, es fehlt der Aufrufer, der danach geordnet herunterfährt.

Kurskorrektur abgeschlossen (R1R7)

IBKRTrader entspricht jetzt strukturell dem PolytraderSharp-Konzept: Multi-Projekt (Core + Modul + App + Tests), Generic Host + IHostedService, IConfiguration, IModule/ModuleView/ShellUiHost, EF Core (extern migriert), Trading-Kern (Risk/Execution/Portfolio, NullBroker-Default), CongressTrading-Strategie, Security (Master-Key/AES-GCM). Offen für später: siehe Roadmap die IBKR-Broker-Anbindung ist inzwischen gebaut, DB-Passwort-Rotation (B1) und EF-Schema (B3) stehen weiterhin aus.


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.