Phase 6 (Stufe 3): CopyTrading-Modul auf EF/MySQL umschaltbar
- CopyTradingDbContext (mod_copytrading_* Tabellen) + Design-Time-Factory - EF-Repos: CopyTradeLog, AccountSettings, TrackedTrader, MasterTraderHistory - Neue Repo-Contracts ITrackedTraderRepository + IMasterTraderHistoryRepository (loest die Collection-Inkonsistenz trackers/tracked_traders auf eine Quelle auf) - Mongo-Impls der neuen Contracts (Uebergang) - CopyTradingModule.RegisterServices: Provider-Toggle (MySql via EF / Mongo) - StartupHydrationService + MasterTraderAnalyticsJob nutzen die Repos statt _db - InitialCopyTrading-Migration erstellt und auf MySQL angewendet Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d8cfdbf6be
commit
8101b79cfb
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PolyTraderSharp.Extensions;
|
||||
using PolyTrader.Modules.CopyTrading.Persistence;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
@@ -16,16 +15,18 @@ namespace PolyTraderSharp.Services
|
||||
private readonly TradingState _state;
|
||||
private readonly CopyTradingState _copyState;
|
||||
private readonly TerminalLogger _logger;
|
||||
private readonly IMongoDatabase _db;
|
||||
private readonly IMasterTraderHistoryRepository _historyRepo;
|
||||
private readonly ITrackedTraderRepository _traderRepo;
|
||||
private readonly JobStatusRow _jobStatus;
|
||||
private readonly PolymarketApiService _api;
|
||||
|
||||
public MasterTraderAnalyticsJob(TradingState state, CopyTradingState copyState, TerminalLogger logger, IMongoDatabase db, JobManager jobManager, PolymarketApiService api)
|
||||
public MasterTraderAnalyticsJob(TradingState state, CopyTradingState copyState, TerminalLogger logger, IMasterTraderHistoryRepository historyRepo, ITrackedTraderRepository traderRepo, JobManager jobManager, PolymarketApiService api)
|
||||
{
|
||||
_state = state;
|
||||
_copyState = copyState;
|
||||
_logger = logger;
|
||||
_db = db;
|
||||
_historyRepo = historyRepo;
|
||||
_traderRepo = traderRepo;
|
||||
_api = api;
|
||||
|
||||
_jobStatus = new JobStatusRow
|
||||
@@ -87,9 +88,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
_logger.Info("🔄 Starte Master-Trader Historien-Download und Performance-Analyse...");
|
||||
|
||||
var historyColl = _db.GetCollection<MasterTraderHistoryRecord>("mt_history");
|
||||
historyColl.EnsureIndex(x => x.TraderId);
|
||||
historyColl.EnsureIndex(x => x.ClosedAt);
|
||||
_historyRepo.EnsureIndexes();
|
||||
|
||||
DateTime cutoff7Days = DateTime.UtcNow.AddDays(-7);
|
||||
var tradersToAnalyze = _copyState.Traders.Values.Where(t => t.IsActive && !string.IsNullOrEmpty(t.WalletAddress)).ToList();
|
||||
@@ -145,7 +144,7 @@ namespace PolyTraderSharp.Services
|
||||
DateTime windowStart = closedTs.AddSeconds(-2);
|
||||
DateTime windowEnd = closedTs.AddSeconds(2);
|
||||
|
||||
bool exists = historyColl.LiteFindOne(x => x.TraderId == trader.Id && x.TokenId == tokenId && x.ClosedAt >= windowStart && x.ClosedAt <= windowEnd) != null;
|
||||
bool exists = _historyRepo.Exists(trader.Id, tokenId, windowStart, windowEnd);
|
||||
if (!exists)
|
||||
{
|
||||
var record = new MasterTraderHistoryRecord
|
||||
@@ -155,7 +154,7 @@ namespace PolyTraderSharp.Services
|
||||
ClosedAt = closedTs,
|
||||
RealizedPnl = pnl
|
||||
};
|
||||
historyColl.Insert(record);
|
||||
_historyRepo.Insert(record);
|
||||
inserted++;
|
||||
}
|
||||
}
|
||||
@@ -164,7 +163,7 @@ namespace PolyTraderSharp.Services
|
||||
await Task.Delay(200);
|
||||
|
||||
// 2. Calculate Stats from DB
|
||||
var last7DaysTrades = historyColl.LiteFind(x => x.TraderId == trader.Id && x.ClosedAt >= cutoff7Days).ToList();
|
||||
var last7DaysTrades = _historyRepo.GetByTraderSince(trader.Id, cutoff7Days);
|
||||
|
||||
trader.TotalTrades = last7DaysTrades.Count;
|
||||
trader.TotalPnl = (double)last7DaysTrades.Sum(x => x.RealizedPnl);
|
||||
@@ -174,8 +173,7 @@ namespace PolyTraderSharp.Services
|
||||
trader.Winrate30t = trader.TotalTrades > 0 ? Math.Round(((double)trader.WinningTrades / trader.TotalTrades) * 100, 2) : 0;
|
||||
|
||||
// Save updated trader to DB so UI updates
|
||||
var tColl = _db.GetCollection<TrackedTrader>("tracked_traders");
|
||||
tColl.Update(trader);
|
||||
_traderRepo.Update(trader);
|
||||
|
||||
if (inserted > 0 && trader.TotalTrades > 0)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace PolyTraderSharp.Services
|
||||
private readonly IAccountRepository _accountRepo;
|
||||
private readonly IPositionRepository _positionRepo;
|
||||
private readonly ICopyTradingAccountSettingsRepository _accountSettingsRepo;
|
||||
private readonly ITrackedTraderRepository _traderRepo;
|
||||
private readonly IMongoDatabase _db;
|
||||
private readonly TerminalLogger _logger;
|
||||
|
||||
@@ -34,6 +35,7 @@ namespace PolyTraderSharp.Services
|
||||
IAccountRepository accountRepo,
|
||||
IPositionRepository positionRepo,
|
||||
ICopyTradingAccountSettingsRepository accountSettingsRepo,
|
||||
ITrackedTraderRepository traderRepo,
|
||||
IMongoDatabase db,
|
||||
TerminalLogger logger)
|
||||
{
|
||||
@@ -42,6 +44,7 @@ namespace PolyTraderSharp.Services
|
||||
_accountRepo = accountRepo;
|
||||
_positionRepo = positionRepo;
|
||||
_accountSettingsRepo = accountSettingsRepo;
|
||||
_traderRepo = traderRepo;
|
||||
_db = db;
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -65,10 +68,7 @@ namespace PolyTraderSharp.Services
|
||||
|
||||
HydrateAccountSettings(accounts);
|
||||
|
||||
// Trader (TrackedTrader) sind aktuell noch modulnah; bis zum Trader-Repo in
|
||||
// Phase 5 direkt aus der "trackers"-Collection geladen.
|
||||
var tradersCol = _db.GetCollection<TrackedTrader>("trackers");
|
||||
foreach (var trd in tradersCol.Find(_ => true).ToList())
|
||||
foreach (var trd in _traderRepo.GetAll())
|
||||
{
|
||||
_copyState.Traders[trd.Id] = trd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user