Fruehjahrsputz: toter Code, ungenutzte Symbole, Dokumentenstand

Alles Entfernte war nachweislich ohne Aufrufer. Build, 198/198 Tests, Smoke-UI
und Daemon-Prueflauf sind vor und nach jedem Schritt gruen.

Code:
  - AIModelService: Platzhalter, der immer 0.5 lieferte. Im DI registriert,
    aber nie irgendwo injiziert. Ordner Core/AI faellt mit weg.
  - CtApiWrapper + CtMeta: JSON-Modelle fuer einen {data,meta}-Umschlag, den
    CapitolTrades nicht mehr liefert. Der Scraper deserialisiert seit laengerem
    direkt List<CtTrade>.
  - IBKRGatewayService: DisconnectAsync, InitBrokerageSessionAsync und
    SearchStocksBySymbolAsync. Der Dienst selbst bleibt - er versorgt
    Instrument-Sync, Kurshistorie und den Watchdog-Heartbeat.
  - Je eine Methode ohne Aufrufer: BudgetService.GetAvailableBudgetAsync,
    TradeHistoryService.GetRecentTradesAsync, CongressRepository.
    GetAllTradeIdsAsync und .ResetHistoryImportAsync, IbkrMapping.DefaultPortFor,
    SecretProtection.IsEncrypted.
  - CongressRepository bekam damit einen LoggingService injiziert, den es nicht
    mehr benutzt - Abhaengigkeit samt Konstruktorparameter raus.

Ressourcen:
  - 17 Symbole der WinForms-Oberflaeche entfernt. Das Wildcard-Muster im csproj
    nahm sie in die Binaerdatei auf, ViewIcons.cs bildet aber nur sieben
    Schluessel ab. Resources/ enthaelt jetzt genau die sieben.

NuGet-Allowlist:
  - Dapper und HtmlAgilityPack sind seit R3 bzw. R1 aus dem Projekt raus,
    Microsoft.WindowsDesktop.* seit L5. Muster entfernt.
  - MySqlConnector und Newtonsoft.Json stehen NUR transitiv in den
    Projektdateien und wurden zuerst mitentfernt - ein Restore in einen leeren
    Paket-Ordner scheiterte darauf mit NU1100. Beide wieder aufgenommen, jetzt
    mit Begruendung, damit der naechste Aufraeumlauf nicht dieselbe Falle tritt.

Dokumente an den tatsaechlichen Stand angeglichen:
  - ARCHITECTURE: R2 fuehrte die Umstellung auf IHostedService als offen, obwohl
    R4 sie erledigt hat. L6 und die Deploymentcenter-Phase fehlten ganz.
  - DC-Konzept: Schritte 0-8 standen auf "dieser Durchlauf", sind aber umgesetzt.
    Jetzt je Schritt der wirkliche Stand - inklusive der beiden Halbfertigen:
    Update-PRUEFUNG laeuft, das Anwenden hat keinen Aufrufer; die
    Release-Pipeline steht, ist aber nie gelaufen. P5 ist eingetreten.
  - Accounting und Supervisor trugen keinen Umsetzungsvermerk, obwohl beide
    Module gebaut sind. Vermerk nach dem Muster des Linux-Konzepts ergaenzt,
    mit dem, was jeweils offen bleibt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-08-23 12:25:03 +02:00
co-authored by Claude Opus 5
parent 0a72ea7e28
commit e1546bd1b1
33 changed files with 78 additions and 163 deletions
-24
View File
@@ -1,24 +0,0 @@
using IBKRTrader.Core.Logging;
namespace IBKRTrader.Core.AI;
/// <summary>
/// Platzhalter für KI-Modell-Integration.
/// Wird in einer späteren Phase mit echten ML-Modellen ersetzt.
/// </summary>
public class AIModelService
{
private readonly LoggingService _logger;
public AIModelService(LoggingService logger)
{
_logger = logger;
}
/// <summary>Platzhalter: Gibt immer 0.5 zurück (keine echte Vorhersage).</summary>
public Task<double> PredictAsync(string symbol, object features)
{
_logger.Warn("AI", $"AIModelService ist ein Platzhalter – keine echte Vorhersage für {symbol}.");
return Task.FromResult(0.5);
}
}
@@ -19,13 +19,6 @@ public class BudgetService
_logger = logger;
}
public async Task<decimal> GetAvailableBudgetAsync(string module)
{
await using var db = await _dbf.CreateDbContextAsync();
var b = await db.Budgets.FindAsync(module);
return b is null ? 0m : b.TotalBudget - b.UsedBudget;
}
public async Task ReserveBudgetAsync(string module, decimal amount)
{
await using var db = await _dbf.CreateDbContextAsync();
@@ -119,26 +119,6 @@ public class IBKRGatewayService
}
}
/// <summary>
/// Initialisiert die Brokerage-Session über den Gateway.
/// </summary>
public async Task<bool> InitBrokerageSessionAsync(CancellationToken ct = default)
{
try
{
await RateLimitAsync(ct);
var body = new StringContent("{\"publish\":true,\"compete\":true}",
System.Text.Encoding.UTF8, "application/json");
var response = await _http.PostAsync("iserver/auth/ssodh/init", body, ct);
return response.IsSuccessStatusCode;
}
catch (Exception ex)
{
_logger.Warn("IBKR", $"Brokerage-Session-Init fehlgeschlagen: {ex.Message}");
return false;
}
}
// ─── Contract Search ─────────────────────────────────────────────────────
/// <summary>
@@ -198,33 +178,6 @@ public class IBKRGatewayService
}
}
/// <summary>
/// Sucht Aktien-Contracts nach Symbolen.
/// GET /trsrv/stocks?symbols=AAPL,MSFT
/// </summary>
public async Task<Dictionary<string, List<IBKRStockContract>>?> SearchStocksBySymbolAsync(
string symbols, CancellationToken ct = default)
{
try
{
await RateLimitAsync(ct);
var response = await _http.GetAsync($"trsrv/stocks?symbols={Uri.EscapeDataString(symbols)}", ct);
if (!response.IsSuccessStatusCode)
{
_logger.Warn("IBKR", $"Stock-Suche fehlgeschlagen: HTTP {(int)response.StatusCode}");
return null;
}
return await response.Content.ReadFromJsonAsync<Dictionary<string, List<IBKRStockContract>>>(JsonOpts, ct);
}
catch (Exception ex)
{
_logger.Error("IBKR", $"Stock-Suche fehlgeschlagen: {ex.Message}", ex);
return null;
}
}
// ─── Historical Market Data ──────────────────────────────────────────────
/// <summary>
@@ -263,12 +216,4 @@ public class IBKRGatewayService
return null;
}
}
// ─── Disconnect ──────────────────────────────────────────────────────────
public Task DisconnectAsync()
{
IsConnected = false;
return Task.CompletedTask;
}
}
@@ -92,10 +92,6 @@ public static class SecretProtection
return Encoding.UTF8.GetString(pt);
}
/// <summary>True, wenn der Wert bereits im verschlüsselten Format vorliegt.</summary>
public static bool IsEncrypted(string? value) =>
!string.IsNullOrEmpty(value) && value!.StartsWith(Prefix, StringComparison.Ordinal);
private static byte[] DeriveKey(string raw)
{
// 32-Byte-Key als Base64?
@@ -33,10 +33,6 @@ internal static class IbkrMapping
return null;
}
/// <summary>Der zum Handelsmodus passende Gateway-Port.</summary>
public static int DefaultPortFor(TradingMode mode) =>
mode == TradingMode.Live ? GatewayLivePort : GatewayPaperPort;
/// <summary>US-Aktie über die SMART-Route – der einzige Instrumententyp, den die Module handeln.</summary>
public static Contract Stock(string symbol) => new()
{
@@ -42,13 +42,4 @@ public class TradeHistoryService
_logger.Info(module, $"Trade gespeichert: {action} {quantity}x {symbol} @ {price:F2}");
}
public async Task<IReadOnlyList<CoreTrade>> GetRecentTradesAsync(int limit = 100)
{
await using var db = await _dbf.CreateDbContextAsync();
return await db.TradeHistory
.OrderByDescending(t => t.TradedAt)
.Take(limit)
.ToListAsync();
}
}