Fix global PNL

This commit is contained in:
2025-09-25 23:23:53 +07:00
parent c297429b18
commit b2e38811ed
5 changed files with 52 additions and 3 deletions

View File

@@ -28,6 +28,7 @@ public interface ITradingRepository
Task<IEnumerable<Position>> GetPositionsByInitiatorIdentifierAsync(Guid initiatorIdentifier);
Task<IEnumerable<Position>> GetPositionsByInitiatorIdentifiersAsync(IEnumerable<Guid> initiatorIdentifiers);
Task<IEnumerable<Position>> GetAllPositionsAsync();
Task<decimal> GetGlobalPnLFromPositionsAsync();
Task UpdateScenarioAsync(Scenario scenario);
Task UpdateStrategyAsync(IndicatorBase indicatorBase);

View File

@@ -39,6 +39,7 @@ public interface ITradingService
Task<IEnumerable<Position>> GetAllDatabasePositionsAsync();
Task<IEnumerable<Position>> GetPositionsByInitiatorIdentifierAsync(Guid initiatorIdentifier);
Task<IEnumerable<Position>> GetPositionsByInitiatorIdentifiersAsync(IEnumerable<Guid> initiatorIdentifiers);
Task<decimal> GetGlobalPnLFromPositionsAsync();
Task<PrivyInitAddressResponse> InitPrivyWallet(string publicAddress, TradingExchanges tradingExchange);
// Synth API integration methods

View File

@@ -106,9 +106,11 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
var totalAgents = agents.Count();
var totalActiveStrategies = strategies.Count(s => s.Status == BotStatus.Running);
// Calculate volume and PnL from strategies
// Calculate volume from strategies
var totalVolume = strategies.Sum(s => s.Volume);
var totalPnL = strategies.Sum(s => s.Pnl);
// Calculate PnL directly from database positions (closed positions only)
var totalPnL = await _tradingService.GetGlobalPnLFromPositionsAsync();
// Calculate real open interest and position count from actual positions
var (totalOpenInterest, totalPositionCount) = await CalculatePositionMetricsAsync();
@@ -317,7 +319,11 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
}
_state.State.TotalPlatformVolume += evt.Volume;
_state.State.TotalPlatformPnL += evt.RealizedPnL;
// PnL is now calculated directly from database positions, not from events
// This ensures accuracy and prevents double-counting issues
// Refresh PnL from database to get the latest accurate value
await RefreshPnLFromDatabaseAsync();
// Update volume by asset
var asset = evt.Ticker;
@@ -452,6 +458,20 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
await _state.WriteStateAsync();
}
private async Task RefreshPnLFromDatabaseAsync()
{
try
{
var totalPnL = await _tradingService.GetGlobalPnLFromPositionsAsync();
_state.State.TotalPlatformPnL = totalPnL;
_logger.LogDebug("Refreshed PnL from database: {TotalPnL}", totalPnL);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error refreshing PnL from database");
}
}
private bool IsDataStale()
{
var timeSinceLastUpdate = DateTime.UtcNow - _state.State.LastUpdated;

View File

@@ -273,6 +273,11 @@ public class TradingService : ITradingService
return await _tradingRepository.GetPositionsByInitiatorIdentifiersAsync(initiatorIdentifiers);
}
public async Task<decimal> GetGlobalPnLFromPositionsAsync()
{
return await _tradingRepository.GetGlobalPnLFromPositionsAsync();
}
private async Task ManageTrader(TraderFollowup a, List<Ticker> tickers)
{
var shortAddress = a.Account.Address.Substring(0, 6);

View File

@@ -505,6 +505,28 @@ public class PostgreSqlTradingRepository : ITradingRepository
return PostgreSqlMappers.Map(positions);
}
public async Task<decimal> GetGlobalPnLFromPositionsAsync()
{
try
{
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
// Calculate total PnL from all finished positions (closed positions)
// Only include positions that are Finished or Flipped (closed positions)
var totalPnL = await _context.Positions
.AsNoTracking()
.Where(p => p.Status == PositionStatus.Finished || p.Status == PositionStatus.Flipped)
.SumAsync(p => p.ProfitAndLoss)
.ConfigureAwait(false);
return totalPnL;
}
finally
{
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
}
}
#endregion
#region Signal Methods