R1: Umbau auf Multi-Projekt-Struktur (Vorbild PolytraderSharp)

Kurskorrektur: Vorbild ist PolytraderSharp (C#), nicht die veraltete Python-Version.
Reiner Strukturumbau, Verhalten unveraendert.

- src/IBKRTrader.Core (classlib): Core-Code + UI-Contract (ModuleFormBase, WindowManager)
- src/IBKRTrader.Modules.CongressTrading (classlib, referenziert nur Core)
- Root: IBKRTrader.App (WinExe) referenziert Core + Modul
- tests/IBKRTrader.Tests: Referenzen auf Core + Modul
- Neue .slnx; ungenutztes HtmlAgilityPack entfernt
- docs/ARCHITECTURE.md: korrigierter Ziel-Stand + R-Phasenplan
- Build + 38/38 Tests gruen; App startet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
This commit is contained in:
Richard
2026-07-27 20:26:25 +02:00
parent 2ad4b55db1
commit c20538c8d8
61 changed files with 171 additions and 129 deletions
+17 -8
View File
@@ -6,23 +6,32 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<!-- Nur englische Satellitenassemblies kein Sprachmüll im Build-Ordner -->
<SatelliteResourceLanguages>en</SatelliteResourceLanguages> <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode> <ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
<!-- Test-Projekt liegt in einem Unterordner: aus dem rekursiven SDK-Globbing des <AssemblyName>IBKRTrader.App</AssemblyName>
Hauptprojekts ausschließen, sonst kompiliert IBKRTrader die Testdateien mit. --> <RootNamespace>IBKRTrader</RootNamespace>
<DefaultItemExcludes>$(DefaultItemExcludes);IBKRTrader.Tests\**</DefaultItemExcludes>
</PropertyGroup> </PropertyGroup>
<!-- Core-, Modul- und Testprojekte liegen unter src/ bzw. tests/ und werden separat kompiliert. -->
<ItemGroup> <ItemGroup>
<PackageReference Include="MySqlConnector" Version="2.4.0" /> <Compile Remove="src\**" />
<PackageReference Include="Dapper" Version="2.1.35" /> <None Remove="src\**" />
<EmbeddedResource Remove="src\**" />
<Compile Remove="tests\**" />
<None Remove="tests\**" />
<EmbeddedResource Remove="tests\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.72" /> </ItemGroup>
<ItemGroup>
<ProjectReference Include="src\IBKRTrader.Core\IBKRTrader.Core.csproj" />
<ProjectReference Include="src\IBKRTrader.Modules.CongressTrading\IBKRTrader.Modules.CongressTrading.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<!-- settings.json immer in Ausgabeverzeichnis kopieren (wenn neuer) -->
<None Update="settings.json"> <None Update="settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
+4 -2
View File
@@ -1,4 +1,6 @@
<Solution> <Solution>
<Project Path="IBKRTrader.csproj" /> <Project Path="IBKRTrader.App.csproj" />
<Project Path="IBKRTrader.Tests/IBKRTrader.Tests.csproj" /> <Project Path="src/IBKRTrader.Core/IBKRTrader.Core.csproj" />
<Project Path="src/IBKRTrader.Modules.CongressTrading/IBKRTrader.Modules.CongressTrading.csproj" />
<Project Path="tests/IBKRTrader.Tests/IBKRTrader.Tests.csproj" />
</Solution> </Solution>
+92 -116
View File
@@ -1,138 +1,114 @@
# IBKRTrader Architektur & Implementierungsplan # IBKRTrader Architektur & Implementierungsplan
Umbau von IBKRTrader auf das **Polytrader-Grundprinzip**: > **KORRIGIERT (2026-07-27):** Vorbild ist **PolytraderSharp** (`J:\Softwareprojekte\PolytraderSharp`),
**harter Core + beliebig viele unabhängige Module + ein Launcher, der die Fenster der > die C#-Neuentwicklung **nicht** die veraltete Python-Version. Die frühere Fassung dieses Plans
einzelnen Module öffnet.** Statt Polymarket wird über Interactive Brokers gehandelt. > basierte auf der Python-Vorlage und war konzeptionell falsch. Ziel ist eine **1:1-Neu-Fundamentierung**
> nach PolytraderSharp, im bestehenden IBKRTrader-Repo.
> Polytrader dient als *konzeptionelle* Vorlage (Python/FastAPI + tkinter-Launcher + Web-UI), Ziel: modulares C#-Trading-Framework für Interactive-Brokers-Aktien, strukturell wie PolytraderSharp,
> nicht als Code-Vorlage. IBKRTrader ist ein C#/.NET-10-WinForms-Framework. nur dass statt Polymarket über IBKR gehandelt wird.
--- ---
## 1. Zielarchitektur ## 1. Ziel-Architektur (nach PolytraderSharp)
``` ```
Program.cs (DI-Bootstrap) 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)
├── CORE (harter Kern kennt KEIN Modul) ├── src/IBKRTrader.Core (classlib, net10.0-windows, UseWindowsForms)
│ ├── Settings AppSettings + settings.json │ ├── Modularity/ IModule (Name, DbPrefix, RegisterServices, RegisterUi, Start/Stop, ActivationBlocker)
├── Logging rtb + Logs/[Modul]/[Level] │ ModuleView, IModuleUiHost, WindowMenu ← UI-Contract liegt im Core
│ ├── Database MySQL/Dapper + Migrationen (core_) │ ├── Configuration/ DatabaseOptions, ServerVersion-Pinning
│ ├── IBKR Marktdaten [vorhanden] + Orders [neu] │ ├── DependencyInjection/ AddCorePersistence(...)
│ ├── Portfolio Positionen/Balance/P&L (core_) [neu] │ ├── Persistence/Ef/ CoreDbContext + Entities + EF-Repositories (hinter Interfaces)
│ ├── Execution + Risk Signal → Prüfung → Order → Buchung [neu] │ ├── Trading/ Broker-Seam, Risk, Execution, Portfolio, Domänentypen
│ ├── Workers WorkerEngine + Core-Worker │ ├── Services/ TerminalLogger, JobManager, Hosted Services (Market-Sync etc.)
── Modules IModule-Vertrag + ModuleRegistry [neu] ── Security/ SecretProtection (Master-Key, AES-256-GCM at-rest)
│ └── Hosting/ StartupHydrationService (IHostedService, hydriert State zuerst)
├── MODULES (unabhängige Strategien Abhängigkeit nur Modul → Core) ├── src/IBKRTrader.Modules.CongressTrading (classlib, referenziert NUR Core)
── CongressTrading Scraper + Repo + Worker [vorhanden] ── CongressTradingModule : IModule
+ Strategie + Fenster [neu] ├── Persistence/Ef/ eigener DbContext (ct_) + Repos
│ ├── Services/ Scraper + Jobs (IHostedService)
│ └── Ui/ CongressTradingMainForm (Tabs) via RegisterUi
└── UI └── tests/IBKRTrader.Tests (xUnit, referenziert Core + Module)
├── 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`) ### Leitprinzipien (aus PolytraderSharp übernommen)
- Core kennt kein Modul. Module hängen sich über DI + `IModule` ein. Abhängigkeit nur Modul → Core. - **Multi-Projekt**: Core = eigenes Assembly; jedes Modul = eigenes Projekt, referenziert **nur** Core.
- DB-Tabellen: `{ModulKürzel}_name` (Core = `core_`, CongressTrading = `ct_`). Module können einander physisch nicht referenzieren.
- Jeder Worker ist unabhängig ein-/ausschaltbar, hat eigenen Zeitplan, ist manuell triggerbar. - **Generic Host**: `Host.CreateDefaultBuilder`, `IHostedService` für alle Hintergrund-Jobs,
- **Strategie lebt im Modul, nicht im Core.** Der Core stellt nur Primitive bereit `IOptions`/`IConfiguration`.
(Orders, Portfolio, Risiko); das Modul liefert nur ein `TradeSignal` an den `ExecutionService`. - **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`.
### Festgelegte Entscheidungen ---
| Thema | Festlegung |
## 2. Was aus dem bisherigen Stand übernommen wird
| Bestand (Phase 03, Python-basiert) | Schicksal |
|---|---| |---|---|
| Modul-Fenster | Eigenständige Top-Level-Fenster; Launcher trackt `Key → Form`, fokussiert bei Re-Open | | Testprojekt (xUnit) | bleibt, wandert nach `tests/` |
| Demo-Betrieb | IBKR **Paper-Account** (Port 4002); Umschaltung Paper/Live via `TradingSettings.Mode` | | `RiskService`, `ExecutionService`, Domänentypen | Logik bleibt → Core/Trading (Feinschliff) |
| Tests | `IBKRTrader.Tests` (xUnit + NSubstitute + FluentAssertions), **nur Unit**, alles Externe gemockt | | CongressTrading Scraper/Repo | Inhalt bleibt → eigenes Modul-Projekt (auf EF/IHostedService umgestellt) |
| DoD je Phase | `dotnet test` (Unit) grün **und** Build sauber | | `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` |
--- ---
## 2. Abbildung Polytrader → IBKRTrader ## 3. Re-Fundamentierungs-Phasen (Checkliste)
| Polytrader | Rolle | IBKRTrader | ### R1 Solution-Skelett (Multi-Projekt, reiner Strukturumbau, Verhalten unverändert) ✅
|---|---|---| - [x] `src/IBKRTrader.Core` (classlib, UseWindowsForms) `Core/` + UI-Contract (`Ui/ModuleFormBase`, `Ui/WindowManager`)
| `main.py` + `api/server.py` lifespan | Entry-Point, Orchestrierung, Background-Loops | `Program.cs` (DI) + `WorkerEngine` | - [x] `src/IBKRTrader.Modules.CongressTrading` (classlib, referenziert nur Core)
| `config.py` | zentrale Config | `SettingsService` / `AppSettings` | - [x] Root-Projekt → `IBKRTrader.App` (WinExe), referenziert Core + Modul; Program/LauncherForm/UI-Shell bleiben
| `database/` | Buchführung | `DatabaseService` + Migrationen + Repos | - [x] `tests/IBKRTrader.Tests` Referenzen auf Core + Modul; Fixture-Pfad angepasst
| `polymarket_client.py` | Plattform-Anbindung | `IIbkrClient` (Marktdaten + Orders) | - [x] Neue `.slnx`; ungenutztes HtmlAgilityPack entfernt; Build + **38/38 Tests grün**; App startet
| `trade_manager.py` | Positionen/Balance/P&L | `PortfolioService` |
| `trade_engine.py` | Signal → Risiko → Order | `ExecutionService` + `RiskService` | ### R2 Core-Contracts + Generic Host + Shell-UI
| `trader_monitor.py` | Datenquelle pollen → Signal | Modul-Worker (z. B. `CT-ScrapeWorker`) | - [ ] `IModule` (PolytraderSharp-Stil) + `ModuleView` + `IModuleUiHost` + `WindowMenu` in Core
| `demo_wallet.py` | Handel ohne echtes Geld | IBKR Paper-Account | - [ ] `Program.cs``Host.CreateDefaultBuilder`; `IConfiguration` (appsettings.json + appsettings.Local.json)
| `desktop_gui.py` | Launcher-Fenster | `LauncherForm` | - [ ] `ShellUiHost` + `LauncherForm` (View-Buttons + Fenster-Menü); Core-Views registrieren
| `frontend/` (Sidebar → Pages) | Ansichten | Launcher-Panels + je Modul ein Fenster | - [ ] CongressTrading auf neuen `IModule`-Vertrag; Module über `IHostedService`
| `telegram_notifier.py` | Benachrichtigungen | `NotificationService` (später) | - [ ] `--smoke-ui` Headless-Test
| `module_checker.py` | Integritätscheck | Startup-Self-Check (später) |
### R3 Persistenz auf EF Core
- [ ] `AddCorePersistence` + `CoreDbContext` + Entities + EF-Repos (core_)
- [ ] Modul-DbContext (ct_) im CongressTrading-Projekt
- [ ] Dapper/manuelle Migrationen entfernen
### R4 Trading-Kern einфügen
- [ ] Risk/Execution/Portfolio/Broker-Seam nach Core/Trading (aus Phase 3 portiert)
- [ ] Hintergrund-Jobs als `IHostedService`
### R5 CongressTrading als vollständige Strategie
- [ ] Scraper/Jobs → `IHostedService`; Signal → `ExecutionService`
- [ ] Modul-View (Tabs) via `RegisterUi`
### R6 Sicherheit + Config-Härtung
- [ ] `SecretProtection` (Master-Key, AES-256-GCM at-rest), TLS-Warnung
- [ ] Connection-String nur in `appsettings.Local.json` (gitignored); Secrets aus Repo/Historie
### R7 Tests + Feinschliff
- [ ] Bestehende Unit-Tests portieren; `--smoke-ui`; EF-InMemory-Tests wo sinnvoll
--- ---
## 3. Teststrategie ## 4. Historie (bereits erledigt, teils zu ersetzen)
- Phase 03 (Python-basiert): Testfundament, IModule/ModuleRegistry, LauncherForm+WindowManager,
- Eigenes Projekt **`IBKRTrader.Tests`** (`net10.0-windows`), im `.slnx`. Trading-Kern (Risk/Execution/Portfolio, NullBroker). Logik brauchbar, Infrastruktur wird ersetzt.
- **Nur Unit-Tests**, deterministisch, schnell, laufen bei jedem Build/Commit. - Commits bis `2ad4b55` auf Gitea.
- 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) ✅
- [x] `Core/Modules/IModule.cs` (`Key`, `DisplayName`, `Description`, `Version`, `RegisterServices`, `InitializeAsync`, `GetWorkers`, `CreateWindow`)
- [x] `Core/Modules/ModuleRegistry.cs`
- [x] `CongressTradingModule``IModule` (instanzbasiert, + Platzhalter-`CreateWindow`)
- [x] `Program.cs` iteriert über `IModule[]` + `ModuleRegistry`; `Form1` initialisiert Module über die Registry
- [x] Testbarkeits-Seams: `WorkerBase.BeginRunLogAsync/EndRunLogAsync`, `CapitolTradesScraper.ParseTradesFromHtml`
- [x] Tests: `ModuleRegistry`, `CongressTradingModule`, `WorkerBase`, `CapitolTradesScraper` (gegen `ct_raw.html`) → **15/15 grün**
### Phase 2 Launcher-UI + Modul-Fenster ✅
- [x] `Form1``LauncherForm` (Dateien via `git mv`, Designer/resx angepasst); Kern-Panels behalten
- [x] Modul-Tab: Karten aus `ModuleRegistry`, je Modul „Fenster öffnen"
- [x] `UI/ModuleFormBase.cs` + `UI/WindowManager.cs` (Fenster-Tracking, Re-Open fokussiert, `CloseAll`)
- [x] `Modules/CongressTrading/UI/CongressTradingForm.cs` (DB-Kennzahlen + „Scrape jetzt")
- [x] `WindowManager` in DI; Launcher schließt Modul-Fenster beim Beenden
- [x] Tests: `WindowManager` (6) → **21/21 grün**; Launcher-Start verifiziert
### Phase 3 Trading-Kern (Core) ✅
- [x] `Core/Trading/TradingModels.cs` (Signal, Order, RiskContext/Decision, Account, Position, Quote)
- [x] `Core/Trading/IBrokerClient.cs` + **`NullBrokerClient`** (sicherer Default: handelt nie)
- [x] `Core/Trading/PortfolioService.cs` (+ `IPortfolioService`) + Migration `core_position` (nutzt vorhandene `core_trade_history`/`core_budget`)
- [x] `Core/Trading/RiskService.cs` (+ `IRiskService`): Sizing, Modul-Limit, Slippage
- [x] `Core/Trading/ExecutionService.cs` (+ `IExecutionService`): Signal → Kurs → Konto → Risiko → Order → Buchung
- [x] `TradingSettings` in `AppSettings` (Mode Paper/Live, TradingEnabled, Risikoparameter)
- [x] Tests: `RiskService` (11), `ExecutionService` (6, voll gemockt) → **38/38 grün**
- [ ] **Offen (bewusst):** echter `IbkrBrokerClient` (Quote/Konto/Order gegen Client-Portal-Gateway) — manuelle Verifikation gegen Paper-Account
### 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)
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Der Core stellt den UI-Contract (ModuleFormBase/WindowManager, später IModuleUiHost/ModuleView)
bereit, damit Module designbare Forms beitragen können. -->
<UseWindowsForms>true</UseWindowsForms>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySqlConnector" Version="2.4.0" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.4" />
</ItemGroup>
<!-- Erlaubt dem Testprojekt, interne Helfer zu testen. -->
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>IBKRTrader.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Modul trägt eigene WinForms-UI (Modul-Fenster) bei. -->
<UseWindowsForms>true</UseWindowsForms>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IBKRTrader.Core\IBKRTrader.Core.csproj" />
</ItemGroup>
<!-- Erlaubt dem Testprojekt, interne Service-Methoden zu testen. -->
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>IBKRTrader.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Project>
@@ -17,15 +17,17 @@
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" /> <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageReference Include="NSubstitute" Version="5.3.0" /> <PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="FluentAssertions" Version="7.0.0" /> <PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\IBKRTrader.csproj" /> <ProjectReference Include="..\..\src\IBKRTrader.Core\IBKRTrader.Core.csproj" />
<ProjectReference Include="..\..\src\IBKRTrader.Modules.CongressTrading\IBKRTrader.Modules.CongressTrading.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<!-- Test-Fixture: gespeicherte capitoltrades.com-Seite (kein Netzzugriff im Test) --> <!-- Test-Fixture: gespeicherte capitoltrades.com-Seite (kein Netzzugriff im Test) -->
<Content Include="..\ct_raw.html" Link="Fixtures\ct_raw.html"> <Content Include="..\..\ct_raw.html" Link="Fixtures\ct_raw.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>