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>
18 KiB
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.0ohne Plattformbindung. Die WinForms-Shell ist entfernt; der letzte Stand liegt im Tagwinforms-final. Einstiegspunkte sind jetztIBKRTrader.App(mit Oberfläche) undIBKRTrader.Daemon(kopflos, systemd); beide bauen ihren Host überIBKRTrader.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,IHostedServicefü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-uikonstruiert jede View + Launcher ohne Message-Loop. - Module an/aus über
ServerSettings.DisabledModules.
2. Was aus dem bisherigen Stand übernommen wird
| Bestand (Phase 0–3, 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+WindowMenuin CoreProgram.cs→Host.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 alsIWorkerregistriert --smoke-uiHeadless-Test (alle Views + Launcher konstruieren) → grün- Worker von
WorkerEngine/IWorkeraufIHostedServiceumgestellt — 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-MigrationInitialCoreerzeugt - Slice 2:
PortfolioService,BudgetService,TradeHistoryServiceauf EF (IDbContextFactory<CoreDbContext>) umgestellt; 5 EF-InMemory-Unit-Tests (Buchführung real verifiziert). WorkerBase-Log folgt in Slice 4. - Slice 3: Modul auf EF (
CongressTradingDbContextct_ +CongressRepository);WorkerBase-Log auf EF (core_worker_log);CoreSettingsService(core_settings);CoreMigrations/CongressMigrations(Dapper) entfernt; EF-MigrationInitialCongressTrading;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 imCoreDbContext, Cross-Modul-Query via Raw-SQL); MigrationAddIbkr; Dapper +DatabaseService+IBKRMigrationsvollstä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(envIBKRTRADER_MYSQL)
R4 – Worker auf IHostedService ✅
WorkerBaseimplementiertIHostedService;IWorkerauf Metadaten+Trigger reduziert- Worker via
AddHostedServiceregistriert; Lebenszyklus überAppHost.Start()/StopAsync() WorkerEngineauf leichte Registry reduziert (WorkerInfos für UI +TriggerWorkerAsync)LauncherFormstartet/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-IExecutionServiceCongressScrapeWorkerruft 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) +NullBrokerClientsicher aus, bis echter Broker + Freigabe
R6 – Sicherheit + Config-Härtung ✅
SecretProtection(Master-Key aus envIBKRTRADER_MASTER_KEY/master.key, AES-256-GCM at-rest, selbstheilendesenc:v1:-Format) +EncryptedStringConverter(bereit für künftige IBKR-Credentials)ConfigureSecretProtection+ TLS-Warnung (SslMode) beim Start;master.keygitignored- 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, Commitebeb035); EF-Schema perdotnet ef database updateauf 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-uideckt 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 überIBKRSettings.UseTwsApi;NullBrokerClientbleibt 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 nebenIBrokerClient, Grundlage für den Abgleich der eigenen Buchführung; gegen DUR371528 verifiziert (2 Positionen, 2 Ausführungen inkl. Kommissionen)- Offen → Roadmap H1 / H2:
PlaceOrderAsyncmit echter Ausführung verifizieren (Fill → Buchung); asynchrone Fill-Verfolgung (Orders ohne sofortige Ausführung) - Offen → Roadmap H3: IBKR-Account-Credentials mit
EncryptedStringConverterspeichern
L0–L5 – 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.configrepariert – drei Pakete hatten keinpackageSourceMapping-Muster; ein frischer Klon konnte nicht wiederherstellen (auf dem Entwicklungsrechner unsichtbar, weil gecacht) - L1a Core und Module von WinForms entkoppelt:
net10.0stattnet10.0-windows. UI-Contract toolkit-neutral (Func<object> CreateView,IconKeystattSystem.Drawing.Image– letzteres ist seit .NET 7 Windows-only).LoggingServicemeldet überEntryWrittenstatt eineRichTextBoxzu halten - L1b Betriebszeitzone (
AppTimeZone,Trading.ApplicationTimeZoneId): EU- und US-Instanzen sauber getrennt, Persistenz bleibt UTC.ParseExecutionTimeverwirft die von TWS gemeldete Börsenzeitzone nicht mehr, sondern rechnet gegen sie nach UTC. Kultur-Fixes (PDF-Beträge festde-DE, Scraper-DatumTryParseExact),BackupWorkerplattformunabhängig, DB-Passwort überMYSQL_PWDstatt Kommandozeile - L2 Kopfloser Dienst
IBKRTrader.Daemon(systemd,--check,--db-version) +IBKRTrader.Hostingals geteilte Host-Zusammenstellung.AppPaths(Umgebungsvariable → Binärverzeichnis wenn beschreibbar → FHS) - L3 Avalonia-Shell (11.3.19, DataGrid 11.3.13) + Core-Ansichten.
PropertyGridersetzt 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.Avalonia→IBKRTrader.App. Das Suffix gab es nur, solange daneben eine WinForms-IBKRTrader.Appstand; seit L5 ist die weg. Assembly, Wurzel-Namensraum und dieavares://-Ressourcen-URI sind mitgezogen, Git erkennt alles als Umbenennung.- Die
global::Avalonia-Qualifizierungen entfallen – sie waren nur nötig, weil der NamensraumIBKRTrader.App.Avaloniadas gleichnamige Paket verdeckte. - Inhaltlich falsch gewordene Aussagen berichtigt – das waren die eigentlichen Überbleibsel,
nicht die Kommentare:
.agents/rules/grundregeln.mdschrieb weiterhin „C# .NET 10 WinForms", RichTextBox-Logging,LauncherFormundPropertyGridvor 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 0–8 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 istIBKRTrader.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 inDirectory.Build.props(P4). - Offen (P5) → Roadmap D1: Die Gitea-CI checkt das Schwester-Repo
Deploymentcenternicht aus. Solange das SDK als Cross-Repo-ProjectReferencehä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
ibkrtraderim DC-WebUI angelegt ist und ein Token mitbugtracker:reportvorliegt (serverseitige Handarbeit). - Offen → Roadmap D3: Das Anwenden eines gefundenen Updates ist nicht verdrahtet.
DcUpdateService.LaunchAgentist fertig und dokumentiert, es fehlt der Aufrufer, der danach geordnet herunterfährt.
Kurskorrektur abgeschlossen (R1–R7)
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 0–3 (Python-basiert): Testfundament, IModule/ModuleRegistry, LauncherForm+WindowManager, Trading-Kern (Risk/Execution/Portfolio, NullBroker). Logik brauchbar, Infrastruktur wird ersetzt.
- Commits bis
2ad4b55auf Gitea.