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>
58 lines
2.9 KiB
C#
58 lines
2.9 KiB
C#
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Configuration;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using PolyTrader.Core.Configuration;
|
||
using PolyTrader.Core.Modularity;
|
||
using PolyTrader.Modules.ResolutionFarming.Persistence;
|
||
using PolyTrader.Modules.ResolutionFarming.Persistence.Ef;
|
||
|
||
namespace PolyTrader.Modules.ResolutionFarming
|
||
{
|
||
/// <summary>
|
||
/// Strategiemodul „ResolutionFarming": kauft systematisch unterbewertete Favoriten (~0.90–0.98)
|
||
/// in bald auflösenden Märkten, hält bis zur Resolution und löst ein (Favorite-Longshot-Reversal).
|
||
/// Erstes neues Strategiemodul über Copytrading hinaus – geringster Infrastrukturbedarf.
|
||
///
|
||
/// Aufbau (inkrementell): geldkritische Entscheidungslogik liegt pur und unit-getestet in
|
||
/// <c>Logic/</c> (FarmingRiskEngine, FarmingScanner, FarmingFillModel); Persistenz, Scanner-Job,
|
||
/// Execution und UI folgen in eigenen Slices. Live-CLOB/On-Chain-Redeem sind Zielland-Arbeit.
|
||
/// </summary>
|
||
public class ResolutionFarmingModule : IPolyTraderModule
|
||
{
|
||
public string Name => "ResolutionFarming";
|
||
public string DbPrefix => "rf_";
|
||
|
||
public void RegisterServices(IServiceCollection services, IConfiguration configuration)
|
||
{
|
||
// Modul-Persistenz: EF Core / Pomelo / MySQL (thread-safer DbContextFactory), eigene rf_-Tabellen.
|
||
var conn = configuration["Database:MySqlConnectionString"] ?? string.Empty;
|
||
services.AddDbContextFactory<ResolutionFarmingDbContext>(o => o.UseMySql(conn, DatabaseServerVersion.Value));
|
||
|
||
services.AddSingleton<IRfSettingsRepository, EfRfSettingsRepository>();
|
||
services.AddSingleton<IRfCandidateRepository, EfRfCandidateRepository>();
|
||
services.AddSingleton<IRfPositionRepository, EfRfPositionRepository>();
|
||
services.AddSingleton<IRfClosedTradeRepository, EfRfClosedTradeRepository>();
|
||
|
||
// 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)
|
||
{
|
||
// Slice 1: noch keine UI-Tabs. Folgen mit Persistenz/Scanner.
|
||
}
|
||
|
||
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||
|
||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||
}
|
||
}
|