Der Core traegt keine WinForms-/System.Drawing-Abhaengigkeit mehr und baut als plattformneutrales net8.0 (verifiziert: publish -r linux-x64 erfolgreich). - ModuleView.CreateForm (Func<Form>) -> CreateView (Func<object>): die Shell kennt ihr Toolkit und castet, der Core nicht. Avalonia kann denselben Contract nutzen. - ModuleView.Icon (System.Drawing.Image, seit .NET 7 Windows-only) -> IconKey (string). Aufloesung Schluessel->Bildressource neu in Ui/ViewIcons.cs, ersetzt Program.AssignMenuIcons. - WindowMenu.cs (reine WinForms-Logik) aus dem Core nach Ui/ verschoben. - WindowMenuTests entfernt: testet die eingefrorene WinForms-Menuelogik, die das Testprojekt nach dem Core-Schnitt nicht mehr erreicht. Im Tag winforms-final erhalten; das Avalonia-Gegenstueck bekommt eigene Tests (P6/P9). Module und App bleiben vorerst net8.0-windows - ihre UI zieht erst mit der Avalonia-Portierung um. Windows-App unveraendert lauffaehig (--smoke-ui gruen). 442 Tests gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
80 lines
4.1 KiB
C#
80 lines
4.1 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>());
|
||
|
||
// Demo-Execution + Resolution-Monitor (Phase RF-2). Marktauflösungs-Quelle vorerst Null
|
||
// (nichts löst auf), bis die Live-Data-API im Zielland verdrahtet ist. Live-Order-Execution
|
||
// und On-Chain-Redeem sind ebenfalls Zielland-Arbeit.
|
||
services.AddSingleton<Services.IMarketResolutionSource, Services.NullMarketResolutionSource>();
|
||
services.AddSingleton<Services.FarmingExecutionService>();
|
||
services.AddHostedService(sp => sp.GetRequiredService<Services.FarmingExecutionService>());
|
||
services.AddSingleton<Services.FarmingResolutionMonitorService>();
|
||
services.AddHostedService(sp => sp.GetRequiredService<Services.FarmingResolutionMonitorService>());
|
||
|
||
// Live-Marktquelle, Live-Execution, On-Chain-Auto-Redeem und Kalibrierung folgen (Zielland).
|
||
}
|
||
|
||
public void RegisterUi(IModuleUiHost host, System.IServiceProvider services)
|
||
{
|
||
// EIN Fenster fürs ganze Modul (Tabs: Kandidaten/Positionen/Historie/Settings).
|
||
host.RegisterView(new ModuleView
|
||
{
|
||
Id = "resolutionfarming.main",
|
||
Title = "ResolutionFarming",
|
||
Group = "ResolutionFarming",
|
||
Order = 200,
|
||
CreateView = () =>
|
||
{
|
||
var form = new Ui.ResolutionFarmingMainForm();
|
||
form.Initialize(services);
|
||
return form;
|
||
}
|
||
});
|
||
}
|
||
|
||
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||
|
||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||
}
|
||
}
|