From 72e07d0c6b9b2ec20d991419042fd83384929666 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 30 Jul 2026 10:09:13 +0200 Subject: [PATCH] @ Doku: IBKR-Integration festgelegt (TWS API / IB Gateway) - docs/IBKR-Integration.md: Entscheidung (TWS API via IB Gateway) + Setup (Ports 4002/4001, IBC/2FA), Regionen (US<->IE gleiche Codebasis), Lib (IB.TWS.CSharpApi), Design des IbkrBrokerClient (async-Wrapper ueber EWrapper/EClient), To-dos bei Gateway-Zugang - ARCHITECTURE.md: Broker-Anbindung als naechsten Meilenstein verankert (blockiert bis Paper-Zugang) Co-Authored-By: Claude Opus 4.8 @ --- docs/ARCHITECTURE.md | 3 ++- docs/IBKR-Integration.md | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 docs/IBKR-Integration.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 409b576..4f247c3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -125,7 +125,8 @@ Pin `new MariaDbServerVersion(new Version(11, 8, 6))`. Verbindung aus `appsettin - [x] Core-**Dashboard-View** (Gesamtüberblick: Trading-Modus, aggregierte Kennzahlen, geladene Module) + Icon - [x] `DashboardService` (aggregiert Positionen/Exposure/Trades via EF) + **2 InMemory-Tests** → 58/58 grün - [x] Tests durchgehend portiert; `--smoke-ui` deckt alle Views ab -- [ ] **Optional/später:** echter `IbkrBrokerClient` gegen Paper-Gateway (braucht laufendes Client-Portal-Gateway); IBKR-Account-Credentials mit `EncryptedStringConverter` speichern +- [ ] **Nächster Meilenstein (blockiert bis Paper-Zugang):** echter `IbkrBrokerClient` über die **TWS API / IB Gateway** (entschieden 2026-07-29). Setup + Design: siehe [IBKR-Integration.md](IBKR-Integration.md). Ports Paper 4002 / Live 4001, region-agnostisch (US↔IE), `NullBroker` bleibt Default bis verifiziert. +- [ ] IBKR-Account-Credentials mit `EncryptedStringConverter` speichern --- diff --git a/docs/IBKR-Integration.md b/docs/IBKR-Integration.md new file mode 100644 index 0000000..1b5fe44 --- /dev/null +++ b/docs/IBKR-Integration.md @@ -0,0 +1,57 @@ +# IBKR-Anbindung – Plan (TWS API via IB Gateway) + +**Entscheidung:** Der `IbkrBrokerClient` (ersetzt `NullBrokerClient`) nutzt die **TWS API** über das +**IB Gateway** – native C#-Lib, robusteste Order-Ausführung, region-agnostisch. + +> Umsetzung ist **blockiert**, bis der Paper-Zugang + ein laufendes IB Gateway verfügbar sind +> (echte Verifikation von Quotes/Konto/Orders nur gegen den Gateway möglich). Dieses Dokument hält +> Setup und Design fest, damit die Umsetzung dann schnell und korrekt läuft. + +## Regionen (US ↔ IE) +Gleiche API, gleiche Gateway-Software, **eine Codebasis**. Unterschied nur: Login/Entity +(Paper: IBKR Ireland, Live später: IBKR LLC US), Marktdaten-Abos, Reports – **kein Code-Fork**. +Paper vs. Live = Konto + Port, kein Code-Unterschied. + +## Betrieb (operativ) +- **IB Gateway** (schlank, statt TWS) muss laufen und eingeloggt sein. +- **Ports:** Paper **4002**, Live **4001** (Auswahl über `TradingSettings.Mode`). + → passt exakt zu den bestehenden `IBKRSettings` (Host `127.0.0.1`, Port, `ClientId`). +- **2FA / Dauerbetrieb:** IBKR erzwingt 2FA und täglichen Neustart. Für unbeaufsichtigten + Server-Betrieb **IBC/IBController** (Auto-Login + geplanter Neustart). + +## Bibliothek +- Empfohlen: offizielle C#-API als NuGet-Mirror **`IB.TWS.CSharpApi`** (keine Abhängigkeiten), + ggf. der vereinfachte Wrapper **`IB.CSharpApiClient`** (mathpaquette) für weniger Callback-Boilerplate. +- NuGet-Allowlist (`NuGet.config`) muss um das Paket ergänzt werden. + +## Design `IbkrBrokerClient : IBrokerClient` +Die TWS API ist **callback-basiert** (`EClientSocket` sendet, `EWrapper` empfängt Events). Wir kapseln +das hinter unserem bestehenden async-Seam `IBrokerClient`: +- **Verbindung:** `EClientSocket.eConnect(host, port, clientId)` + Reader-Thread; Reconnect-Logik. +- **Korrelation:** je Request eine `reqId`; Antworten via `TaskCompletionSource` in einem + `ConcurrentDictionary` auflösen. Timeout je Request. +- **`GetQuoteAsync(symbol)`** → Kontrakt (`reqContractDetails`/`reqMatchingSymbols`) → Snapshot-Kurs + (`reqMktData` snapshot bzw. `reqTickByTickData`) → `Quote(Last, Bid, Ask)`. +- **`GetAccountStateAsync()`** → `reqAccountSummary` (NetLiquidation, AvailableFunds). +- **`PlaceOrderAsync(OrderRequest)`** → `Order` bauen (MKT/LMT, Menge, Side) → `placeOrder(orderId, contract, order)`; + Ergebnis über `orderStatus`/`openOrder`/`execDetails`-Callbacks einsammeln → `OrderResult`. + `nextValidId` liefert die Order-IDs. +- **Sicherheit bleibt:** `NullBrokerClient` bleibt Default; `IbkrBrokerClient` wird erst registriert + (via Config-Schalter), wenn verifiziert. Handel zusätzlich weiter durch `TradingEnabled`-Gate geschützt. + +## Marktdaten +Aktuell laufen die Marktdaten-Worker über die **Client Portal Web API** (`IBKRGatewayService`). +Optionen (später entscheiden): +- Broker (Quotes/Konto/Orders) → TWS API; Marktdaten-Historie **vorerst auf CP Web API belassen**, oder +- Historie ebenfalls auf TWS (`reqHistoricalData`) migrieren → nur noch ein Gateway. + +## Testbarkeit +- Reine Logik (Order-/Kontrakt-Mapping, Response-Parsing) → Unit-Tests möglich. +- Verbindung/Quotes/Orders → **manuell gegen das Paper-Gateway**, sobald verfügbar. + +## To-do bei Gateway-Zugang +1. `IB.TWS.CSharpApi` (+ NuGet-Allowlist) hinzufügen. +2. `IbkrBrokerClient` implementieren (Design oben), hinter Config-Schalter registrieren. +3. `TradingSettings.Mode` → Port 4002/4001; `IBKRSettings.ClientId` nutzen. +4. Gegen Paper verifizieren: Verbindung → Quote → Konto → Test-Order (Paper) → Buchung. +5. IBC für Auto-Login/Neustart einrichten.