Files
PolyTraderSharp/src/PolyTrader.Modules.Supervisor/SupervisorModule.cs
T
RichardandClaude Opus 4.8 c7668170a4 Supervisor S-3-Rest + RF-Designer-Konvertierung: Counterfactual, Tagesbericht, UI
RF-UI designerfaehig (Richards Vorgabe, letzter code-only-Altbestand):
- ResolutionFarmingMainForm auf partial + .Designer.cs umgestellt (4 Tabs Kandidaten/
  Positionen/Historie/Settings, alle Controls im Designer; Verhalten unveraendert).

S-3 Counterfactual ('Was waere aus abgelehnten BUYs geworden?'):
- CounterfactualJob (alle 6h, API-gedrosselt): nimmt Rejected-BUY-Entscheidungen mit
  abgelaufenem MarketEndDate aus dem Journal, prueft die Marktaufloesung
  (ICounterfactualResolutionSource; live = Adapter um CheckMarketResolutionAsync) und
  speichert IsWinner + hypothetischen PnL/Share (CounterfactualMath, pur) nach
  sup_counterfactuals (unique je DecisionId -> idempotent). Migration generiert+angewendet.
- Agent-Tool query_counterfactuals + UI-Tab 'Counterfactual' (via Designer).

S-3 Threema-Tagesbericht:
- DailyReportService: taeglich zur konfigurierten Stunde (OPT-IN via
  POLYTRADER_SUPERVISOR_DAILY=0-23) laesst der Agent einen 24h-Kurzbericht erstellen
  (KPIs je Modul, Fehler, Reject-Haeufungen), sendet via Threema und legt ihn als
  sup_report ab. Ohne OpenRouter-Key: stiller Skip mit Log.

Tests: +7 (CounterfactualMath, Job aufgeloest/unaufgeloest/idempotent, Tagesbericht
mit/ohne Key). Build 0 Fehler, 367 Tests gruen, --smoke-ui alle 5 Views gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 11:14:45 +02:00

79 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PolyTrader.Core.Modularity;
using PolyTrader.Modules.Supervisor.Services;
namespace PolyTrader.Modules.Supervisor
{
/// <summary>
/// Supervisor-Modul (docs/konzepte/KONZEPT-Modul-Supervisor.md): Analyse/Forensik über ALLE
/// Module — strikt read-only (kein Handel). S-1: Dossier-Browser über Entscheidungsjournal,
/// Order-Events, Trade-Log und JSONL-Logs. S-2 (OpenRouter-Agent + Tool-Registry), S-3
/// (Profile/Berichte/Counterfactual/Predictalytics) und S-4 (MCP-Light) folgen.
/// </summary>
public class SupervisorModule : IPolyTraderModule
{
public string Name => "Supervisor";
public string DbPrefix => "sup_";
public void RegisterServices(IServiceCollection services, IConfiguration configuration)
{
// S-1: Dossier-Beschaffung/-Aufbereitung.
services.AddSingleton<DossierService>();
// S-2: read-only Tool-Registry + OpenRouter-Agent. Der API-Key kommt aus
// POLYTRADER_OPENROUTER_KEY bzw. gitignorierter openrouter.key (getrennt vom Trading).
services.AddSingleton(sp => Agent.SupervisorTools.CreateRegistry(
sp.GetRequiredService<PolyTrader.Core.Persistence.IDecisionJournal>(),
sp.GetRequiredService<PolyTrader.Core.Persistence.IOrderEventLog>(),
sp.GetRequiredService<PolyTrader.Core.Persistence.ITradeLogRepository>(),
sp.GetRequiredService<DossierService>(),
sp.GetRequiredService<Persistence.ISupervisorCounterfactualRepository>()));
services.AddSingleton<Agent.IChatCompletionClient>(_ =>
new Agent.OpenRouterClient(new System.Net.Http.HttpClient { Timeout = TimeSpan.FromMinutes(3) }));
services.AddSingleton<Agent.SupervisorAgent>();
// S-3: sup_-Persistenz (gespeicherte Analysen/Berichte).
var conn = configuration["Database:MySqlConnectionString"] ?? string.Empty;
services.AddDbContextFactory<Persistence.SupervisorDbContext>(o =>
o.UseMySql(conn, PolyTrader.Core.Configuration.DatabaseServerVersion.Value));
services.AddSingleton<Persistence.ISupervisorReportRepository, Persistence.EfSupervisorReportRepository>();
services.AddSingleton<Persistence.ISupervisorCounterfactualRepository, Persistence.EfSupervisorCounterfactualRepository>();
// S-3: Counterfactual-Job (abgelehnte BUYs vs. Marktausgang) + täglicher Threema-Bericht
// (OPT-IN via POLYTRADER_SUPERVISOR_DAILY = Stunde 023).
services.AddSingleton<Counterfactual.ICounterfactualResolutionSource, Counterfactual.ApiCounterfactualResolutionSource>();
services.AddHostedService<Counterfactual.CounterfactualJob>();
services.AddHostedService<Services.DailyReportService>();
// S-4: MCP-Light exponiert die read-only Tool-Registry für externe KI-Clients
// (z. B. Claude Code). OPT-IN via POLYTRADER_MCP_PORT, bindet nur 127.0.0.1.
services.AddHostedService<Mcp.McpLightServer>();
}
public void RegisterUi(IModuleUiHost host, System.IServiceProvider services)
{
host.RegisterView(new ModuleView
{
Id = "supervisor.main",
Title = "Supervisor",
Group = "Supervisor",
Order = 300,
CreateForm = () =>
{
var form = new Ui.SupervisorMainForm();
form.Initialize(services);
return form;
}
});
}
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}