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:
co-authored by
Claude Opus 4.8
parent
8e2a92ad2e
commit
4f6c7fdb86
@@ -15,6 +15,7 @@ namespace PolyTrader.Core.DependencyInjection
|
||||
services.AddSingleton<IAccountRepository, MongoAccountRepository>();
|
||||
services.AddSingleton<IMarketRepository, MongoMarketRepository>();
|
||||
services.AddSingleton<IPositionRepository, MongoPositionRepository>();
|
||||
services.AddSingleton<ITradeLogRepository, MongoTradeLogRepository>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
namespace PolyTraderSharp.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Generischer, modulübergreifender Trade-Log-Eintrag (Collection "trade_log").
|
||||
/// Jedes Modul, das Trades abschließt, schreibt hier einen neutralen Eintrag —
|
||||
/// so kann das Core-Dashboard die Trades ALLER Module gemeinsam auswerten.
|
||||
/// Modulspezifische Details (z.B. Copytrading-SourceTrader) bleiben im jeweiligen
|
||||
/// Modul-Log (z.B. ClosedTrade).
|
||||
/// </summary>
|
||||
public class TradeRecord
|
||||
{
|
||||
[MongoDB.Bson.Serialization.Attributes.BsonId]
|
||||
public string Id { get; set; } = MongoDB.Bson.ObjectId.GenerateNewId().ToString();
|
||||
|
||||
/// <summary>Herkunftsmodul, z.B. "CopyTrading".</summary>
|
||||
public string ModuleName { get; set; } = string.Empty;
|
||||
|
||||
public int AccountId { get; set; }
|
||||
public bool IsDemo { get; set; }
|
||||
|
||||
public string TokenId { get; set; } = string.Empty;
|
||||
public string MarketQuestion { get; set; } = string.Empty;
|
||||
public string Outcome { get; set; } = string.Empty;
|
||||
public string Side { get; set; } = string.Empty;
|
||||
|
||||
public decimal EntryPrice { get; set; }
|
||||
public decimal ExitPrice { get; set; }
|
||||
public decimal Size { get; set; }
|
||||
|
||||
public decimal RealizedPnl { get; set; }
|
||||
public decimal PnlPercent { get; set; }
|
||||
|
||||
public DateTime OpenedAt { get; set; }
|
||||
public DateTime ClosedAt { get; set; }
|
||||
public string ExitReason { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using PolyTraderSharp.Models;
|
||||
|
||||
namespace PolyTrader.Core.Persistence
|
||||
{
|
||||
/// <summary>
|
||||
/// Generischer, modulübergreifender Trade-Log (Collection "trade_log").
|
||||
/// Speist das Core-Dashboard mit den Trades aller Module.
|
||||
/// </summary>
|
||||
public interface ITradeLogRepository
|
||||
{
|
||||
void EnsureIndexes();
|
||||
void Insert(TradeRecord record);
|
||||
|
||||
/// <summary>Die neuesten Einträge über alle Module (nach ClosedAt absteigend).</summary>
|
||||
List<TradeRecord> GetRecent(int limit);
|
||||
|
||||
List<TradeRecord> Find(Expression<Func<TradeRecord, bool>> predicate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using MongoDB.Driver;
|
||||
using PolyTraderSharp.Models;
|
||||
|
||||
namespace PolyTrader.Core.Persistence.Mongo
|
||||
{
|
||||
public class MongoTradeLogRepository : ITradeLogRepository
|
||||
{
|
||||
private readonly IMongoCollection<TradeRecord> _col;
|
||||
|
||||
public MongoTradeLogRepository(IMongoDatabase db)
|
||||
{
|
||||
_col = db.GetCollection<TradeRecord>("trade_log");
|
||||
}
|
||||
|
||||
public void EnsureIndexes()
|
||||
{
|
||||
try
|
||||
{
|
||||
_col.Indexes.CreateOne(new CreateIndexModel<TradeRecord>(
|
||||
Builders<TradeRecord>.IndexKeys.Descending(x => x.ClosedAt)));
|
||||
_col.Indexes.CreateOne(new CreateIndexModel<TradeRecord>(
|
||||
Builders<TradeRecord>.IndexKeys.Ascending(x => x.ModuleName)));
|
||||
_col.Indexes.CreateOne(new CreateIndexModel<TradeRecord>(
|
||||
Builders<TradeRecord>.IndexKeys.Ascending(x => x.AccountId)));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public void Insert(TradeRecord record) => _col.InsertOne(record);
|
||||
|
||||
public List<TradeRecord> GetRecent(int limit) =>
|
||||
_col.Find(_ => true).SortByDescending(x => x.ClosedAt).Limit(limit).ToList();
|
||||
|
||||
public List<TradeRecord> Find(Expression<Func<TradeRecord, bool>> predicate) =>
|
||||
_col.Find(predicate).ToList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user