diff --git a/.agents/rules/grundregeln.md b/.agents/rules/grundregeln.md index 7b4d59d..4011fa1 100644 --- a/.agents/rules/grundregeln.md +++ b/.agents/rules/grundregeln.md @@ -3,7 +3,8 @@ trigger: always_on --- Projektname: IBKRTrader -Ziel: Modulares, hochperformantes C# Trading-Framework (.NET 8) für automatische Aktien-Strategien mit Interactive Brokers API. +Ziel: Modulares, hochperformantes C# Trading-Framework (.NET 10) für automatische Aktien-Strategien mit Interactive Brokers API. +Vorbild-Konzept: Polytrader (Core + unabhängige Module + Launcher, der die Fenster der einzelnen Module öffnet). Strikte Architektur-Regeln (immer einhalten): Harter Core + beliebig viele unabhängige Module @@ -16,16 +17,21 @@ Keine gegenseitigen Blockierungen – alles thread-sicher und performant Technik (fest): -C# .NET 8 WinForms -MySQL (bergisnu_db0 / bergisnu_0 / o5/A49+f}:Da / larx.your-database.de) -IBKR TWS/Gateway API +C# .NET 10 WinForms +MySQL – Zugangsdaten NUR in settings.json (gitignored), NIE im Repo/Code/Doku hinterlegen +IBKR TWS/Gateway API (Paper: Port 4002, Live: Port 4001 – Umschaltung über TradingSettings.Mode) Interne REST-API + lokaler Webserver (für späteres Web-UI) -Settings: settings.json + SettingsWorker.json +Settings: settings.json (Vorlage: settings.example.json) Logging: RichTextBox (rtb_logs) + Dateien unter Logs\[Modul]\[Level]-dd-MM-yy.txt (Info/Warn/Error) +Tests: eigenes Projekt IBKRTrader.Tests (xUnit + NSubstitute + FluentAssertions), NUR Unit-Tests, + alles Externe (DB/IBKR/Scraper) gemockt. DoD jeder Phase: `dotnet test` grün + Build sauber. -Bereits vorhandene UI-Elemente (müssen verwendet werden): +UI-Grundmodell (Launcher-Prinzip nach Polytrader): -TabControl mit Tabs: Dashboard, Trade History, Settings (PropertyGrid), Logs (rtb_logs), Workers/Services (dgv_workerlist), CongressTrading +LauncherForm = Basis-Fenster. Enthält: Core-Status/Steuerung ("Trading aktivieren", Paper/Live), + Workers/Services (dgv_workerlist), Logs (rtb_logs), Settings (PropertyGrid) und eine Modul-Liste. +Jedes Modul wird als EIGENSTÄNDIGES Fenster aus dem Launcher geöffnet (nicht als Tab). + Der Launcher trackt offene Fenster (Key → Form) und fokussiert bei erneutem Öffnen. dgv_workerlist Spalten: Active | Type | Module | Workername | Last Runtime | Next Runtime | Run Every | Info Type = "Worker" oder "Service" (Service = permanent laufend) diff --git a/IBKRTrader.Tests/IBKRTrader.Tests.csproj b/IBKRTrader.Tests/IBKRTrader.Tests.csproj new file mode 100644 index 0000000..496d249 --- /dev/null +++ b/IBKRTrader.Tests/IBKRTrader.Tests.csproj @@ -0,0 +1,30 @@ + + + + + net10.0-windows + true + enable + enable + false + en + + + + + + + + + + + + + + + + + + + + diff --git a/IBKRTrader.Tests/SmokeTests.cs b/IBKRTrader.Tests/SmokeTests.cs new file mode 100644 index 0000000..68929df --- /dev/null +++ b/IBKRTrader.Tests/SmokeTests.cs @@ -0,0 +1,29 @@ +using FluentAssertions; +using IBKRTrader.Core.Settings; +using IBKRTrader.Core.Workers; + +namespace IBKRTrader.Tests; + +/// +/// Phase-0-Smoke-Test: bestätigt, dass die Test-Infrastruktur steht und die +/// Referenz auf die Hauptassembly (IBKRTrader) kompiliert und lädt. +/// +[Trait("cat", "unit")] +public class SmokeTests +{ + [Fact] + public void MainAssembly_IsReferenced_AndDefaultsLoad() + { + var settings = new AppSettings(); + + settings.Should().NotBeNull(); + settings.IBKR.Should().NotBeNull(); + settings.Logging.Level.Should().Be("Info"); + } + + [Fact] + public void WorkerType_HasWorkerAndService() + { + Enum.GetNames().Should().Contain(["Worker", "Service"]); + } +} diff --git a/IBKRTrader.csproj b/IBKRTrader.csproj index 8ae8967..1f8b27e 100644 --- a/IBKRTrader.csproj +++ b/IBKRTrader.csproj @@ -9,6 +9,9 @@ en PerMonitorV2 + + $(DefaultItemExcludes);IBKRTrader.Tests\** diff --git a/IBKRTrader.slnx b/IBKRTrader.slnx index 155986b..9a34f62 100644 --- a/IBKRTrader.slnx +++ b/IBKRTrader.slnx @@ -1,3 +1,4 @@ + diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000..adbd11f --- /dev/null +++ b/NuGet.config @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..be8ff0b --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,135 @@ +# IBKRTrader – Architektur & Implementierungsplan + +Umbau von IBKRTrader auf das **Polytrader-Grundprinzip**: +**harter Core + beliebig viele unabhängige Module + ein Launcher, der die Fenster der +einzelnen Module öffnet.** Statt Polymarket wird über Interactive Brokers gehandelt. + +> Polytrader dient als *konzeptionelle* Vorlage (Python/FastAPI + tkinter-Launcher + Web-UI), +> nicht als Code-Vorlage. IBKRTrader ist ein C#/.NET-10-WinForms-Framework. + +--- + +## 1. Zielarchitektur + +``` +Program.cs (DI-Bootstrap) +│ +├── CORE (harter Kern – kennt KEIN Modul) +│ ├── Settings AppSettings + settings.json +│ ├── Logging rtb + Logs/[Modul]/[Level] +│ ├── Database MySQL/Dapper + Migrationen (core_) +│ ├── IBKR Marktdaten [vorhanden] + Orders [neu] +│ ├── Portfolio Positionen/Balance/P&L (core_) [neu] +│ ├── Execution + Risk Signal → Prüfung → Order → Buchung [neu] +│ ├── Workers WorkerEngine + Core-Worker +│ └── Modules IModule-Vertrag + ModuleRegistry [neu] +│ +├── MODULES (unabhängige Strategien – Abhängigkeit nur Modul → Core) +│ └── CongressTrading Scraper + Repo + Worker [vorhanden] +│ + Strategie + Fenster [neu] +│ +└── UI + ├── LauncherForm Basis: Core-Status, Worker-Grid, Logs, Settings, + │ Modul-Liste mit „Fenster öffnen"-Buttons + └── ModuleFormBase Basisklasse für eigenständige Modul-Fenster +``` + +### Kernregeln (siehe auch `.agents/rules/grundregeln.md`) +- Core kennt kein Modul. Module hängen sich über DI + `IModule` ein. Abhängigkeit nur Modul → Core. +- DB-Tabellen: `{ModulKürzel}_name` (Core = `core_`, CongressTrading = `ct_`). +- Jeder Worker ist unabhängig ein-/ausschaltbar, hat eigenen Zeitplan, ist manuell triggerbar. +- **Strategie lebt im Modul, nicht im Core.** Der Core stellt nur Primitive bereit + (Orders, Portfolio, Risiko); das Modul liefert nur ein `TradeSignal` an den `ExecutionService`. + +### Festgelegte Entscheidungen +| Thema | Festlegung | +|---|---| +| Modul-Fenster | Eigenständige Top-Level-Fenster; Launcher trackt `Key → Form`, fokussiert bei Re-Open | +| Demo-Betrieb | IBKR **Paper-Account** (Port 4002); Umschaltung Paper/Live via `TradingSettings.Mode` | +| Tests | `IBKRTrader.Tests` (xUnit + NSubstitute + FluentAssertions), **nur Unit**, alles Externe gemockt | +| DoD je Phase | `dotnet test` (Unit) grün **und** Build sauber | + +--- + +## 2. Abbildung Polytrader → IBKRTrader + +| Polytrader | Rolle | IBKRTrader | +|---|---|---| +| `main.py` + `api/server.py` lifespan | Entry-Point, Orchestrierung, Background-Loops | `Program.cs` (DI) + `WorkerEngine` | +| `config.py` | zentrale Config | `SettingsService` / `AppSettings` | +| `database/` | Buchführung | `DatabaseService` + Migrationen + Repos | +| `polymarket_client.py` | Plattform-Anbindung | `IIbkrClient` (Marktdaten + Orders) | +| `trade_manager.py` | Positionen/Balance/P&L | `PortfolioService` | +| `trade_engine.py` | Signal → Risiko → Order | `ExecutionService` + `RiskService` | +| `trader_monitor.py` | Datenquelle pollen → Signal | Modul-Worker (z. B. `CT-ScrapeWorker`) | +| `demo_wallet.py` | Handel ohne echtes Geld | IBKR Paper-Account | +| `desktop_gui.py` | Launcher-Fenster | `LauncherForm` | +| `frontend/` (Sidebar → Pages) | Ansichten | Launcher-Panels + je Modul ein Fenster | +| `telegram_notifier.py` | Benachrichtigungen | `NotificationService` (später) | +| `module_checker.py` | Integritätscheck | Startup-Self-Check (später) | + +--- + +## 3. Teststrategie + +- Eigenes Projekt **`IBKRTrader.Tests`** (`net10.0-windows`), im `.slnx`. +- **Nur Unit-Tests**, deterministisch, schnell, laufen bei jedem Build/Commit. +- Externe Abhängigkeiten hinter Interfaces (`IIbkrClient`, `IOrderService`, `IPortfolioService`, + `IRiskService`, `ICongressRepository` …) → in Tests via **NSubstitute** gemockt. +- Echtes MySQL/IBKR-Paper/Scraping wird **manuell** je Meilenstein geprüft (nicht automatisiert). + +| Komponente | Beispiel-Testfall | +|---|---| +| `RiskService` | Sizing bei 5 % Budget; Ablehnung bei Slippage; globaler Pause-Schalter blockt | +| `ExecutionService` | Signal → gemockte Risk/Order/Portfolio; Buchung & Ablehnungsgründe | +| `CapitolTradesScraper` | Parser gegen Fixture `ct_raw.html` (deterministisch, kein Netz) | +| `ModuleRegistry` / `IModule` | Registrierung, Worker-Sammlung, `CreateWindow` liefert Fenster | +| `WorkerBase` | Interval-Loop, Trigger, Fehler → `Status=Error`, Cancellation | +| `AppSettings` / `SettingsService` | Laden/Serialisieren, Paper/Live-Port-Auswahl (4002/4001) | +| `WindowManager` | Fenster-Tracking, Re-Open fokussiert bestehendes Fenster | + +WinForms selbst wird **nicht** unit-getestet – Logik in Services/Manager halten, Forms dünn. + +--- + +## 4. Phasenplan (Checkliste) + +### Phase 0 – Fundament & Doku ✅ +- [x] `grundregeln.md` auf .NET 10 + Launcher-Modell aktualisiert (+ DB-Passwort entfernt) +- [x] `docs/ARCHITECTURE.md` angelegt +- [x] `IBKRTrader.Tests` (xUnit + NSubstitute + FluentAssertions) angelegt, im `.slnx` +- [x] Repo-lokale `NuGet.config` (Test-Pakete in Allowlist ergänzt) +- [x] Erster Smoke-Test grün (`dotnet test` → 2/2 bestanden) + +### Phase 1 – Modul-System formalisieren (Refactoring, kein Verhaltensänderung) +- [ ] `Core/Modules/IModule.cs` (`Key`, `DisplayName`, `Description`, `Version`, `RegisterServices`, `InitializeAsync`, `GetWorkers`, `CreateWindow`) +- [ ] `Core/Modules/ModuleRegistry.cs` +- [ ] `CongressTradingModule` → `IModule` +- [ ] `Program.cs` iteriert über Registry statt CongressTrading hart zu nennen +- [ ] Tests: `ModuleRegistry`, `WorkerBase`, `CapitolTradesScraper` (gegen `ct_raw.html`) + +### Phase 2 – Launcher-UI + Modul-Fenster +- [ ] `Form1` → `LauncherForm`; Kern-Panels behalten (Workers, Logs, Settings, Core-Status) +- [ ] Modul-Panel: Liste aus `ModuleRegistry`, je Modul „Fenster öffnen" +- [ ] `UI/ModuleFormBase.cs` + `UI/WindowManager.cs` (Fenster-Tracking) +- [ ] `Modules/CongressTrading/UI/CongressTradingForm.cs` (erstes Modul-Fenster) +- [ ] Tests: `WindowManager` + +### Phase 3 – Trading-Kern (Core) +- [ ] `Core/Trading/IIbkrClient.cs` (+ Adapter auf `IBKRGatewayService`) +- [ ] `Core/Trading/IOrderService.cs` + Implementierung (Market/Limit, Paper+Live) +- [ ] `Core/Trading/PortfolioService.cs` + Migrationen `core_position`, `core_trade`, `core_account_snapshot` +- [ ] `Core/Trading/RiskService.cs` (Sizing, Limits, Slippage, Profit-Target, globaler Pause-Schalter) +- [ ] `Core/Trading/ExecutionService.cs` (`TradeSignal` → Risiko → Order → Buchung) +- [ ] `TradingSettings` in `AppSettings` (Mode Paper/Live, Risikoparameter) +- [ ] Tests: `RiskService`, `ExecutionService` (voll gemockt) + +### Phase 4 – CongressTrading als vollständige Strategie +- [ ] `CongressTradingStrategy`: neue Scrape-Trades → `TradeSignal` an `ExecutionService` +- [ ] Modul-Fenster: offene/geschlossene Positionen, P&L, Strategie-Ein/Aus, Parameter +- [ ] Tests: Signal-Erzeugung + +### Phase 5 – Feinschliff (optional) +- [ ] `NotificationService` (Telegram o. Ä.) + periodische Reports +- [ ] Startup-Self-Check (analog `module_checker`) +- [ ] Dashboard-Panel im Launcher (Gesamt-Balance/P&L über alle Module)