From 76b5036703613ab1bf6ae62bc426c186c214b1ee Mon Sep 17 00:00:00 2001 From: cryptooda Date: Sat, 18 Oct 2025 13:48:12 +0700 Subject: [PATCH] Fix volume over time --- .../Controllers/BacktestController.cs | 5 -- .../Grains/PlatformSummaryGrain.cs | 61 ++++++++++++++----- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/Managing.Api/Controllers/BacktestController.cs b/src/Managing.Api/Controllers/BacktestController.cs index 9788c5ec..797c10da 100644 --- a/src/Managing.Api/Controllers/BacktestController.cs +++ b/src/Managing.Api/Controllers/BacktestController.cs @@ -621,11 +621,6 @@ public class BacktestController : BaseController // Calculate total number of backtests var totalBacktests = request.DateTimeRanges.Count * request.MoneyManagementVariants.Count * request.TickerVariants.Count; - if (totalBacktests > 100) - { - return BadRequest("Maximum of 100 backtests allowed per bundle request"); - } - try { var user = await GetUser(); diff --git a/src/Managing.Application/Grains/PlatformSummaryGrain.cs b/src/Managing.Application/Grains/PlatformSummaryGrain.cs index a27bfc80..00f9072e 100644 --- a/src/Managing.Application/Grains/PlatformSummaryGrain.cs +++ b/src/Managing.Application/Grains/PlatformSummaryGrain.cs @@ -122,8 +122,21 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable var positions = await _tradingService.GetAllDatabasePositionsAsync(); + // Get the last daily snapshot date to calculate cumulative volume + var lastSnapshotDate = _state.State.DailySnapshots.Any() + ? _state.State.DailySnapshots.Max(s => s.Date) + : DateTime.MinValue; + + // Start with the cumulative volume from the last snapshot + var cumulativeVolume = _state.State.DailySnapshots.Any() + ? _state.State.DailySnapshots.OrderByDescending(s => s.Date).First().TotalVolume + : 0m; + + _logger.LogInformation("Calculating cumulative volume from last snapshot date: {LastSnapshotDate}, Base volume: {CumulativeVolume}", + lastSnapshotDate, cumulativeVolume); + // Calculate all metrics from positions in a single loop - var totalVolume = 0m; + var newVolume = 0m; // Volume from positions after last snapshot var totalFees = 0m; var totalPnL = 0m; var totalOpenInterest = 0m; @@ -140,16 +153,17 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable // Calculate volume using the dedicated method var positionVolume = TradingHelpers.GetVolumeForPosition(position); - totalVolume += positionVolume; - // Calculate fees and PnL for all positions - totalFees += position.CalculateTotalFees(); - totalPnL += position.ProfitAndLoss?.Realized ?? 0; + // For cumulative volume: only add volume from positions created AFTER last snapshot + // For volume breakdown: include all positions + if (position.Date.Date > lastSnapshotDate) + { + newVolume += positionVolume; + _logger.LogDebug("Position {PositionId} created after last snapshot ({PositionDate} > {LastSnapshotDate}), adding volume: {Volume}", + position.Identifier, position.Date.Date, lastSnapshotDate, positionVolume); + } - // Count all positions - totalPositionCount++; - - // Calculate breakdown metrics and update state directly + // Calculate breakdown metrics from ALL positions (for current state) var ticker = position.Ticker; var direction = position.OriginDirection; @@ -158,7 +172,6 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable { _state.State.VolumeByAsset[ticker] = 0; } - _state.State.VolumeByAsset[ticker] += positionVolume; // Position count breakdown by asset - update state directly @@ -166,10 +179,16 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable { _state.State.PositionCountByAsset[ticker] = 0; } - _state.State.PositionCountByAsset[ticker]++; - // Position count breakdown by direction - only count finished positions + // Calculate fees and PnL for all positions + totalFees += position.CalculateTotalFees(); + totalPnL += position.ProfitAndLoss?.Realized ?? 0; + + // Count all positions + totalPositionCount++; + + // Position count breakdown by direction - only count open positions if (position.IsOpen()) { var openingVolume = position.Open.Price * position.Open.Quantity * position.Open.Leverage; @@ -184,7 +203,21 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable } } - _state.State.TotalPlatformVolume = totalVolume; + // CUMULATIVE volume: baseline + new volume since last snapshot + var updatedCumulativeVolume = cumulativeVolume + newVolume; + + _logger.LogInformation("Volume calculation: Base={BaseVolume}, New={NewVolume}, Total={TotalVolume}", + cumulativeVolume, newVolume, updatedCumulativeVolume); + + // Ensure volume never decreases + if (updatedCumulativeVolume < _state.State.TotalPlatformVolume) + { + _logger.LogWarning("Calculated cumulative volume ({Calculated}) is less than current volume ({Current}). Keeping current value.", + updatedCumulativeVolume, _state.State.TotalPlatformVolume); + updatedCumulativeVolume = _state.State.TotalPlatformVolume; + } + + _state.State.TotalPlatformVolume = updatedCumulativeVolume; _state.State.TotalPlatformFees = totalFees; _state.State.TotalPlatformPnL = totalPnL; _state.State.NetPnL = totalPnL - totalFees; // Calculate NetPnL @@ -202,7 +235,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable await RefreshAgentCountAsync(); await _state.WriteStateAsync(); - _logger.LogInformation("Platform summary data refreshed successfully"); + _logger.LogInformation("Platform summary data refreshed successfully - Cumulative volume: {Volume}", updatedCumulativeVolume); } catch (Exception ex) {