Phase 5-UI: Generischer Core-Trade-Log + modulübergreifendes Dashboard

- Core: TradeRecord (Modell) + ITradeLogRepository (+ Mongo-Impl, Collection
  "trade_log"), in AddCorePersistence registriert. Realisiert den generischen,
  modulneutralen Trade-Log aus Entscheidung #2.
- Dual-Write: PersistenceService schreibt geschlossene Copy-Trades zusaetzlich als
  generischen TradeRecord (ModuleName="CopyTrading").
- Neue DashboardView (UserControl + Designer): zeigt die letzten Trades ALLER
  Module (GetRecent) mit Konto-Aufloesung + Kurzauswertung (Gesamt-PnL, Anzahl,
  Aufschluesselung je Modul). btn_dashboard im Launcher, View "core.dashboard".
- Build 0 Fehler.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-02 12:16:20 +02:00
co-authored by Claude Opus 4.8
parent 8e2a92ad2e
commit 4f6c7fdb86
13 changed files with 500 additions and 41 deletions
+26 -2
View File
@@ -1,6 +1,7 @@
using System.Threading.Channels;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using PolyTrader.Core.Persistence;
using PolyTrader.Modules.CopyTrading.Persistence;
using PolyTraderSharp.Models;
@@ -10,13 +11,15 @@ namespace PolyTraderSharp.Services
{
private readonly ChannelReader<ClosedTrade> _tradeReader;
private readonly ICopyTradeLogRepository _tradeLog;
private readonly ITradeLogRepository _coreTradeLog;
private readonly TerminalLogger _logger;
private readonly JobStatusRow _jobStatus;
public PersistenceService(ChannelReader<ClosedTrade> tradeReader, ICopyTradeLogRepository tradeLog, TerminalLogger logger, JobManager jobManager)
public PersistenceService(ChannelReader<ClosedTrade> tradeReader, ICopyTradeLogRepository tradeLog, ITradeLogRepository coreTradeLog, TerminalLogger logger, JobManager jobManager)
{
_tradeReader = tradeReader;
_tradeLog = tradeLog;
_coreTradeLog = coreTradeLog;
_logger = logger;
_jobStatus = new JobStatusRow
@@ -43,6 +46,7 @@ namespace PolyTraderSharp.Services
// One-time index setup (moved out of hot loop)
_tradeLog.EnsureIndexes();
_coreTradeLog.EnsureIndexes();
// We do a loop waiting for items in the channel
await foreach(var trade in _tradeReader.ReadAllAsync(stoppingToken))
@@ -72,7 +76,27 @@ namespace PolyTraderSharp.Services
}
_tradeLog.Insert(trade);
// Dual-Write: generischer, modulübergreifender Core-Trade-Log (fürs Dashboard).
_coreTradeLog.Insert(new TradeRecord
{
ModuleName = "CopyTrading",
AccountId = trade.AccountId,
IsDemo = trade.IsDemo,
TokenId = trade.TokenId,
MarketQuestion = trade.MarketQuestion,
Outcome = trade.Outcome,
Side = trade.Side,
EntryPrice = trade.EntryPrice,
ExitPrice = trade.ExitPrice,
Size = trade.Size,
RealizedPnl = trade.RealizedPnl,
PnlPercent = trade.PnlPercent,
OpenedAt = trade.OpenedAt,
ClosedAt = trade.ClosedAt,
ExitReason = trade.ExitReason
});
_logger.Debug($"Saved ClosedTrade {trade.TradeId} to MongoDB");
_jobStatus.LastRun = DateTime.Now;
}