RF-Slice 3: Read-only-Scanner (Bewertungs-Pipeline + Persistenz)

Phase RF-1 (read-only): Scanner holt bald aufloesende Favoriten von einer
IFarmingMarketSource, bewertet sie und schreibt JEDEN Kandidaten (akzeptiert wie
abgelehnt inkl. Grund) nach rf_candidates. Platziert keine Orders.

- MarketScannerService.Evaluate (pur/statisch, voll getestet): Filterkette mit
  Reject-Grund = erster Fehlschlag (Preisband -> Kategorie -> Blacklist ->
  Aufloesungsfenster -> Netto-Edge nach Fees). Cluster-Key + Score immer berechnet.
- ScanAccountAsync: Beschaffung -> Bewertung -> Persistenz. BackgroundService-Loop
  (12min) ueber Accounts mit Settings; fehlertolerant.
- IFarmingMarketSource + ScannedMarket-DTO trennen die (live-/API-gebundene)
  Beschaffung von der Bewertung -> Pipeline ohne echte Gamma/CLOB-API testbar.
- NullFarmingMarketSource als Default: Modul laeuft ohne Live-Anbindung (die im
  Zielland registriert wird) und produziert dann korrekt keine Kandidaten.

Hinweis: Zur Laufzeit fragt der Scanner rf_settings ab; bis die Migration angewendet
ist, faengt der try/catch den fehlenden-Tabelle-Fehler ab (nur Log). Migration bewusst
separat anzuwenden.

7 neue Tests (Evaluate-Faelle + Orchestrierung). Build 0 Fehler, 296 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-09 22:11:11 +02:00
co-authored by Claude Opus 4.8
parent 1b6e194b50
commit ad6c676e60
5 changed files with 327 additions and 1 deletions
@@ -35,7 +35,14 @@ namespace PolyTrader.Modules.ResolutionFarming
services.AddSingleton<IRfPositionRepository, EfRfPositionRepository>();
services.AddSingleton<IRfClosedTradeRepository, EfRfClosedTradeRepository>();
// Scanner-/Monitor-Jobs, Execution und UI folgen in den nächsten Slices.
// Read-only-Scanner (Phase RF-1). Marktquelle vorerst NullFarmingMarketSource: das Modul
// läuft ohne Live-Gamma/CLOB-Anbindung (die im Zielland registriert wird) und produziert
// dann korrekt keine Kandidaten.
services.AddSingleton<Services.IFarmingMarketSource, Services.NullFarmingMarketSource>();
services.AddSingleton<Services.MarketScannerService>();
services.AddHostedService(sp => sp.GetRequiredService<Services.MarketScannerService>());
// Execution, Resolution-Monitor, Auto-Redeem und UI folgen in den nächsten Slices.
}
public void RegisterUi(IModuleUiHost host, System.IServiceProvider services)