Phase 3: Trading-Kern (Risk, Execution, Portfolio) mit sicherem Broker-Default

- Core/Trading/TradingModels: Signal, Order(Request/Result), RiskContext/Decision,
  Account, Position, Quote, ExecutionResult, Enums (Side/OrderType/Mode)
- IBrokerClient + NullBrokerClient (sicherer Default, handelt NIE bis IBKR-Adapter verifiziert)
- RiskService (+IRiskService): Sizing nach MaxTrade%, Modul-Limit, Slippage; Buy/Sell
- PortfolioService (+IPortfolioService): core_position + core_trade_history + core_budget
- ExecutionService (+IExecutionService): Signal -> Kurs -> Konto -> Risiko -> Order -> Buchung
- TradingSettings in AppSettings (Paper/Live, TradingEnabled, Risikoparameter)
- CoreMigrations: core_position; DI-Registrierung der Trading-Services
- Tests: RiskService (11) + ExecutionService (6, NSubstitute) -> 38/38 gruen

Offen (bewusst gekapselt): echter IbkrBrokerClient gegen Client-Portal-Gateway (manuell verifizieren).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
This commit is contained in:
Richard
2026-07-27 11:33:59 +02:00
parent d0bc833235
commit 2ad4b55db1
15 changed files with 833 additions and 8 deletions
+17
View File
@@ -0,0 +1,17 @@
namespace IBKRTrader.Core.Trading;
/// <summary>
/// Broker-Abstraktion (Kurse, Konto, Order-Ausführung).
/// Externer Seam: in Tests gemockt, produktiv von einem IBKR-Adapter implementiert.
/// </summary>
public interface IBrokerClient
{
/// <summary>Aktuelle Kurs-Momentaufnahme oder null, wenn nicht verfügbar.</summary>
Task<Quote?> GetQuoteAsync(string symbol, CancellationToken ct = default);
/// <summary>Kontostand-Momentaufnahme.</summary>
Task<AccountState> GetAccountStateAsync(CancellationToken ct = default);
/// <summary>Platziert eine Order und gibt das Ergebnis zurück.</summary>
Task<OrderResult> PlaceOrderAsync(OrderRequest request, CancellationToken ct = default);
}