RF-Slice 5: Demo-Execution + Resolution-Monitor (Phase RF-2)

Schliesst die Demo-Handelsschleife des ResolutionFarming:
- FarmingExecutionPlanner (pur): waehlt aus akzeptierten Kandidaten die zu oeffnenden
  Positionen + Groesse, priorisiert nach Score, unter Markt-/Cluster-/Gesamt-Limits,
  Kill-Switch und Tages-Drossel; dedupliziert Token, schreibt Exposure im Lauf fort.
- FarmingResolution (pur): baut aus Position + Ergebnis den RfClosedTrade (PnL/Fees/Redeem-Status).
- FarmingExecutionService: Demo-Einstieg (Maker-Fill 0 Fee via FarmingFillModel) -> rf_positions.
  Live-Execution bewusst geloggt/uebersprungen (Zielland). Demo-Balance NICHT mutiert
  (kein Shared-Account-Konflikt; PnL fliesst ueber rf_closed_trades).
- FarmingResolutionMonitorService: schliesst aufgeloeste Positionen, bucht GlobalPnl,
  Dual-Write ins Core-Trade-Log (Dashboard). Auflösungsstatus via IMarketResolutionSource.
- NullMarketResolutionSource als Default (nichts loest auf), bis Live-Data-API verdrahtet ist.

15 neue Tests (Planner 8, Resolution 3, Execution-Service 2, Monitor 2). Build 0 Fehler,
311 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-10 11:40:30 +02:00
co-authored by Claude Opus 4.8
parent 80e6ad9b2d
commit 1c3a364df2
11 changed files with 680 additions and 1 deletions
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using PolyTrader.Core.Persistence;
using PolyTraderSharp.Models;
namespace PolyTrader.Tests.Fakes
{
/// <summary>In-Memory-Stub für den generischen Core-Trade-Log (Dual-Write-Ziel der Module).</summary>
public sealed class FakeCoreTradeLogRepository : ITradeLogRepository
{
public List<TradeRecord> Inserted { get; } = new();
public void EnsureIndexes() { }
public void Insert(TradeRecord record) => Inserted.Add(record);
public List<TradeRecord> GetRecent(int limit) => Inserted.TakeLast(limit).ToList();
public List<TradeRecord> Find(Expression<Func<TradeRecord, bool>> predicate) => Inserted.Where(predicate.Compile()).ToList();
}
}