Fix active strategy count on plateform surmmary

This commit is contained in:
2025-11-21 20:02:33 +07:00
parent 153e170ca4
commit 476bcebfe9
2 changed files with 37 additions and 70 deletions

View File

@@ -45,29 +45,6 @@ public class PlatformSummaryGrainState
// Flag to track if volume has been updated by events (not from bot strategies) // Flag to track if volume has been updated by events (not from bot strategies)
[Id(15)] public bool VolumeUpdatedByEvents { get; set; } [Id(15)] public bool VolumeUpdatedByEvents { get; set; }
// Historical strategy activation/deactivation events
[Id(16)] public List<StrategyEvent> StrategyEvents { get; set; } = new();
}
/// <summary>
/// Strategy activation/deactivation event
/// </summary>
[GenerateSerializer]
public class StrategyEvent
{
[Id(0)] public DateTime Timestamp { get; set; }
[Id(1)] public StrategyEventType EventType { get; set; }
[Id(2)] public int NetChange { get; set; } // +1 for activation, -1 for deactivation
}
/// <summary>
/// Type of strategy event
/// </summary>
public enum StrategyEventType
{
Activation,
Deactivation
} }
/// <summary> /// <summary>

View File

@@ -1,5 +1,6 @@
using Managing.Application.Abstractions; using Managing.Application.Abstractions;
using Managing.Application.Abstractions.Grains; using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Repositories;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Application.Orleans; using Managing.Application.Orleans;
using Managing.Domain.Candles; using Managing.Domain.Candles;
@@ -19,6 +20,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
{ {
private readonly IPersistentState<PlatformSummaryGrainState> _state; private readonly IPersistentState<PlatformSummaryGrainState> _state;
private readonly IBotService _botService; private readonly IBotService _botService;
private readonly IBotRepository _botRepository;
private readonly IAgentService _agentService; private readonly IAgentService _agentService;
private readonly ITradingService _tradingService; private readonly ITradingService _tradingService;
private readonly ILogger<PlatformSummaryGrain> _logger; private readonly ILogger<PlatformSummaryGrain> _logger;
@@ -29,12 +31,14 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
[PersistentState("platform-summary-state", "platform-summary-store")] [PersistentState("platform-summary-state", "platform-summary-store")]
IPersistentState<PlatformSummaryGrainState> state, IPersistentState<PlatformSummaryGrainState> state,
IBotService botService, IBotService botService,
IBotRepository botRepository,
IAgentService agentService, IAgentService agentService,
ITradingService tradingService, ITradingService tradingService,
ILogger<PlatformSummaryGrain> logger) ILogger<PlatformSummaryGrain> logger)
{ {
_state = state; _state = state;
_botService = botService; _botService = botService;
_botRepository = botRepository;
_agentService = agentService; _agentService = agentService;
_tradingService = tradingService; _tradingService = tradingService;
_logger = logger; _logger = logger;
@@ -195,32 +199,6 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
newActiveCount = 0; newActiveCount = 0;
} }
var previousCount = _state.State.TotalActiveStrategies;
var change = newActiveCount - previousCount;
// Record the strategy event if there was a change
if (change != 0)
{
var eventType = change > 0 ? StrategyEventType.Activation : StrategyEventType.Deactivation;
var strategyEvent = new StrategyEvent
{
Timestamp = DateTime.UtcNow,
EventType = eventType,
NetChange = change
};
_state.State.StrategyEvents.Add(strategyEvent);
// Keep only last 1000 events to prevent unbounded growth
if (_state.State.StrategyEvents.Count > 1000)
{
_state.State.StrategyEvents.RemoveRange(0, _state.State.StrategyEvents.Count - 1000);
}
_logger.LogInformation("Recorded strategy {EventType} event: {Change} strategies at {Timestamp}",
eventType, change, strategyEvent.Timestamp);
}
_state.State.TotalActiveStrategies = newActiveCount; _state.State.TotalActiveStrategies = newActiveCount;
await _state.WriteStateAsync(); await _state.WriteStateAsync();
} }
@@ -306,7 +284,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
{ {
Date = today, Date = today,
TotalAgents = _state.State.TotalAgents, TotalAgents = _state.State.TotalAgents,
TotalStrategies = CalculateActiveStrategiesForDate(today), TotalStrategies = await CalculateActiveStrategiesForDateAsync(today), // Use bot entity data
TotalVolume = _state.State.TotalPlatformVolume, TotalVolume = _state.State.TotalPlatformVolume,
TotalPnL = _state.State.TotalPlatformPnL, TotalPnL = _state.State.TotalPlatformPnL,
NetPnL = _state.State.NetPnL, NetPnL = _state.State.NetPnL,
@@ -348,38 +326,50 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
} }
/// <summary> /// <summary>
/// Calculates the number of active strategies on a specific date by replaying historical events /// Calculates the number of active strategies on a specific date by querying bot entities
/// Uses LastStartTime, LastStopTime, and Status to determine activity
/// </summary> /// </summary>
/// <param name="targetDate">The date to calculate active strategies for</param> /// <param name="targetDate">The date to calculate active strategies for</param>
/// <returns>The number of active strategies on the target date</returns> /// <returns>The number of active strategies on the target date</returns>
private int CalculateActiveStrategiesForDate(DateTime targetDate) private async Task<int> CalculateActiveStrategiesForDateAsync(DateTime targetDate)
{ {
try try
{ {
// Start with 0 active strategies var today = DateTime.UtcNow.Date;
var bots = await _botRepository.GetBotsAsync();
var activeCount = 0; var activeCount = 0;
// Replay all strategy events up to and including the target date foreach (var bot in bots)
var relevantEvents = _state.State.StrategyEvents
.Where(e => e.Timestamp.Date <= targetDate.Date)
.OrderBy(e => e.Timestamp)
.ToList();
foreach (var strategyEvent in relevantEvents)
{ {
activeCount += strategyEvent.NetChange; var wasActive = false;
// Ensure we don't go below 0 (defensive programming) // If target date is today, check current status
if (activeCount < 0) if (targetDate.Date == today)
{ {
_logger.LogWarning("Active strategy count went negative ({Count}) after event {EventType} at {Timestamp}, resetting to 0", wasActive = bot.Status == BotStatus.Running;
activeCount, strategyEvent.EventType, strategyEvent.Timestamp); }
activeCount = 0; else
{
// For historical dates, use start/stop times
// Bot was active if it was started on or before the target date
// and either never stopped or stopped after the target date
if (bot.LastStartTime.HasValue)
{
var wasStarted = bot.LastStartTime.Value.Date <= targetDate.Date;
var wasNotStopped = !bot.LastStopTime.HasValue || bot.LastStopTime.Value.Date > targetDate.Date;
wasActive = wasStarted && wasNotStopped;
}
}
if (wasActive)
{
activeCount++;
} }
} }
_logger.LogDebug("Calculated {ActiveCount} active strategies for date {TargetDate} based on {EventCount} historical events", _logger.LogDebug("Calculated {ActiveCount} active strategies for date {TargetDate} from {TotalBots} total bots",
activeCount, targetDate.Date, relevantEvents.Count); activeCount, targetDate.Date, bots.Count());
return activeCount; return activeCount;
} }
@@ -588,9 +578,9 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
// Use TradingBox to calculate metrics for filtered positions // Use TradingBox to calculate metrics for filtered positions
var metrics = TradingBox.CalculatePlatformSummaryMetrics(filteredPositions); var metrics = TradingBox.CalculatePlatformSummaryMetrics(filteredPositions);
// Get historical agent and strategy counts for the target date // Get agent count and calculate active strategies for the target date using bot entity data
var totalAgents = await _agentService.GetTotalAgentCount(); var totalAgents = await _agentService.GetTotalAgentCount();
var totalStrategies = CalculateActiveStrategiesForDate(targetDate); var totalStrategies = await CalculateActiveStrategiesForDateAsync(targetDate);
_logger.LogInformation( _logger.LogInformation(
"Calculated CUMULATIVE snapshot for {TargetDate}: Volume={TotalVolume}, OpenInterest={OpenInterest}, PositionCount={TotalPositionCount}, Fees={Fees}, PnL={PnL}", "Calculated CUMULATIVE snapshot for {TargetDate}: Volume={TotalVolume}, OpenInterest={OpenInterest}, PositionCount={TotalPositionCount}, Fees={Fees}, PnL={PnL}",