Phase 3d (1/2): TraderMonitorService auf Repositories umgestellt
- 8 Positions-Zugriffe (open_positions_{id}) -> IPositionRepository
(FindLive/UpsertLive/DeleteLive).
- 1 Market-Upsert -> IMarketRepository.
- closed_trades bleibt auf _db (ClosedTrade-Repo folgt in Phase 5).
- Verhalten unverändert (Repos bilden Shim-Semantik 1:1 nach); Build 0 Fehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using MongoDB.Driver;
|
||||
using PolyTrader.Core.Persistence;
|
||||
using PolyTraderSharp.Extensions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
@@ -21,7 +22,9 @@ namespace PolyTraderSharp.Services
|
||||
private readonly ChannelWriter<ClosedTrade> _closedTradeWriter;
|
||||
private readonly TerminalLogger _logger;
|
||||
private readonly IMongoDatabase? _db;
|
||||
|
||||
private readonly IPositionRepository _positionRepo;
|
||||
private readonly IMarketRepository _marketRepo;
|
||||
|
||||
// Prevents duplicates. Fast O(1) lookup cache to prevent DB spam.
|
||||
private readonly ConcurrentDictionary<string, DateTime> _processedTxHashes = new();
|
||||
private DateTime _lastHashCleanup = DateTime.UtcNow;
|
||||
@@ -42,6 +45,8 @@ namespace PolyTraderSharp.Services
|
||||
ChannelWriter<CopySignal> signalWriter,
|
||||
ChannelWriter<ClosedTrade> closedTradeWriter,
|
||||
TerminalLogger logger,
|
||||
IPositionRepository positionRepo,
|
||||
IMarketRepository marketRepo,
|
||||
IMongoDatabase? db = null)
|
||||
{
|
||||
_state = state;
|
||||
@@ -50,6 +55,8 @@ namespace PolyTraderSharp.Services
|
||||
_signalWriter = signalWriter;
|
||||
_closedTradeWriter = closedTradeWriter;
|
||||
_logger = logger;
|
||||
_positionRepo = positionRepo;
|
||||
_marketRepo = marketRepo;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
@@ -332,8 +339,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
_ = Task.Run(() => {
|
||||
try {
|
||||
var mdColl = _db.GetCollection<MarketData>("markets");
|
||||
mdColl.Upsert(coldItem);
|
||||
_marketRepo.Upsert(coldItem);
|
||||
} catch { } // Failsafe
|
||||
});
|
||||
}
|
||||
@@ -549,8 +555,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var liveCol = _db.GetCollection<Position>($"open_positions_{acc.AccountId}");
|
||||
var dbPos = liveCol.LiteFindOne(x => x.TokenId == asset);
|
||||
var dbPos = _positionRepo.FindLive(acc.AccountId, asset);
|
||||
if (dbPos != null && dbPos.SourceTraderId > 0)
|
||||
{
|
||||
resolvedSourceId = dbPos.SourceTraderId;
|
||||
@@ -705,7 +710,7 @@ namespace PolyTraderSharp.Services
|
||||
existing.CurrentValueUsd = curValue;
|
||||
if (expiry.HasValue) existing.ExpiryDate = expiry;
|
||||
|
||||
if (_db != null) { try { _db.GetCollection<Position>($"open_positions_{acc.AccountId}").Upsert(existing); } catch { } }
|
||||
try { _positionRepo.UpsertLive(acc.AccountId, existing); } catch { }
|
||||
|
||||
// Auto-Redeem Fallback via REST
|
||||
if (acc.PreRedeemLimit > 0 && curPrice >= acc.PreRedeemLimit && acc.IsActive)
|
||||
@@ -791,8 +796,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var liveCol = _db.GetCollection<Position>($"open_positions_{acc.AccountId}");
|
||||
var dbPos = liveCol.LiteFindOne(x => x.TokenId == asset);
|
||||
var dbPos = _positionRepo.FindLive(acc.AccountId, asset);
|
||||
if (dbPos != null)
|
||||
{
|
||||
if (dbPos.SourceTraderId > 0)
|
||||
@@ -829,7 +833,7 @@ namespace PolyTraderSharp.Services
|
||||
OpenedAt = resolvedOpenedAt
|
||||
};
|
||||
acc.OpenPositions.TryAdd(asset, newPos);
|
||||
if (_db != null) { try { _db.GetCollection<Position>($"open_positions_{acc.AccountId}").Upsert(newPos); } catch { } }
|
||||
try { _positionRepo.UpsertLive(acc.AccountId, newPos); } catch { }
|
||||
|
||||
if (resolvedTraderId > 0)
|
||||
_logger.Info($"🌐 Live Position erkannt: {title} ({newPos.Outcome}) - ${amountUsd} - Account: {acc.Name} [Zugeordnet: {resolvedTraderName}]");
|
||||
@@ -857,8 +861,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
var liveCol = _db.GetCollection<Position>($"open_positions_{acc.AccountId}");
|
||||
var dbPos = liveCol.LiteFindOne(x => x.TokenId == k);
|
||||
var dbPos = _positionRepo.FindLive(acc.AccountId, k);
|
||||
if (dbPos != null && dbPos.SourceTraderId > 0)
|
||||
{
|
||||
removedPos.SourceTraderId = dbPos.SourceTraderId;
|
||||
@@ -880,8 +883,8 @@ namespace PolyTraderSharp.Services
|
||||
if (matchedClose.HasValue)
|
||||
{
|
||||
acc.OpenPositions.TryRemove(k, out _); // Safe removal!
|
||||
if (_db != null) { try { _db.GetCollection<Position>($"open_positions_{acc.AccountId}").Delete(k); } catch { } }
|
||||
|
||||
try { _positionRepo.DeleteLive(acc.AccountId, k); } catch { }
|
||||
|
||||
decimal realizedPnl = 0m;
|
||||
DateTime resolvedClosedAt = DateTime.UtcNow;
|
||||
|
||||
@@ -953,8 +956,8 @@ namespace PolyTraderSharp.Services
|
||||
if (isClosed)
|
||||
{
|
||||
acc.OpenPositions.TryRemove(k, out _); // Safe removal!
|
||||
if (_db != null) { try { _db.GetCollection<Position>($"open_positions_{acc.AccountId}").Delete(k); } catch { } }
|
||||
|
||||
try { _positionRepo.DeleteLive(acc.AccountId, k); } catch { }
|
||||
|
||||
decimal exitPrice = isWinner ? 1.0m : 0.0m;
|
||||
decimal exitUsd = removedPos.Size * exitPrice;
|
||||
decimal realizedPnl = exitUsd - removedPos.AmountUsd;
|
||||
@@ -1029,7 +1032,7 @@ namespace PolyTraderSharp.Services
|
||||
{
|
||||
if (acc.OpenPositions.TryRemove(k, out _))
|
||||
{
|
||||
if (_db != null) { try { _db.GetCollection<Position>($"open_positions_{acc.AccountId}").Delete(k); } catch { } }
|
||||
try { _positionRepo.DeleteLive(acc.AccountId, k); } catch { }
|
||||
_logger.Info($"🌐 Live Position {removedPos.MarketQuestion} final entfernt (Ext. Verkauft/Wartend nach {ageMinutes:F0} Min.)");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user