Clean and update event
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#nullable enable
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Grains;
|
||||
using Managing.Application.Abstractions.Models;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Bots.Models;
|
||||
using Managing.Application.Orleans;
|
||||
@@ -91,40 +91,107 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
_logger.LogInformation("Agent {UserId} updated with name {AgentName}", this.GetPrimaryKeyLong(), agentName);
|
||||
}
|
||||
|
||||
public async Task OnAgentSummaryUpdateAsync(AgentSummaryUpdateEvent updateEvent)
|
||||
public async Task OnPositionOpenedAsync(PositionOpenEvent evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Received agent summary update event for user {UserId}, event type: {EventType}",
|
||||
this.GetPrimaryKeyLong(), updateEvent.EventType);
|
||||
_logger.LogInformation("Position opened event received for user {UserId}, position: {PositionId}",
|
||||
this.GetPrimaryKeyLong(), evt.PositionIdentifier);
|
||||
|
||||
// Only update summary if the event is for this agent's bots
|
||||
if (_state.State.BotIds.Contains(updateEvent.BotId))
|
||||
{
|
||||
await UpdateSummary();
|
||||
}
|
||||
// Update event-driven metrics
|
||||
_state.State.TotalVolume += evt.Volume;
|
||||
_state.State.TotalFees += evt.Fee;
|
||||
_state.State.LastSummaryUpdate = DateTime.UtcNow;
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
// Update the agent summary with the new data
|
||||
await UpdateSummary();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing agent summary update event for user {UserId}",
|
||||
_logger.LogError(ex, "Error processing position opened event for user {UserId}",
|
||||
this.GetPrimaryKeyLong());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task UpdateSummary()
|
||||
public async Task OnPositionClosedAsync(PositionClosedEvent evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get all bots for this agent
|
||||
var bots = await _botService.GetBotsByIdsAsync(_state.State.BotIds);
|
||||
_logger.LogInformation("Position closed event received for user {UserId}, position: {PositionId}, PnL: {PnL}",
|
||||
this.GetPrimaryKeyLong(), evt.PositionIdentifier, evt.RealizedPnL);
|
||||
|
||||
// Calculate aggregated statistics from bot data
|
||||
var totalPnL = bots.Sum(b => b.Pnl);
|
||||
var totalWins = bots.Sum(b => b.TradeWins);
|
||||
var totalLosses = bots.Sum(b => b.TradeLosses);
|
||||
// Update event-driven metrics
|
||||
_state.State.TotalPnL += evt.RealizedPnL;
|
||||
_state.State.TotalVolume += evt.Volume;
|
||||
|
||||
// Update wins/losses count
|
||||
if (evt.RealizedPnL > 0)
|
||||
{
|
||||
_state.State.Wins++;
|
||||
}
|
||||
else if (evt.RealizedPnL < 0)
|
||||
{
|
||||
_state.State.Losses++;
|
||||
}
|
||||
|
||||
_state.State.LastSummaryUpdate = DateTime.UtcNow;
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
// Update the agent summary with the new data
|
||||
await UpdateSummary();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing position closed event for user {UserId}",
|
||||
this.GetPrimaryKeyLong());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OnPositionUpdatedAsync(PositionUpdatedEvent evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Position updated event received for user {UserId}, position: {PositionId}",
|
||||
this.GetPrimaryKeyLong(), evt.PositionIdentifier);
|
||||
|
||||
// Update event-driven metrics for PnL changes
|
||||
// Note: This is for real-time PnL updates, not cumulative like closed positions
|
||||
_state.State.LastSummaryUpdate = DateTime.UtcNow;
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
|
||||
// Update the agent summary with the new data
|
||||
await UpdateSummary();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error processing position updated event for user {UserId}",
|
||||
this.GetPrimaryKeyLong());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the agent summary by recalculating from position data (used for initialization or manual refresh)
|
||||
/// </summary>
|
||||
private async Task UpdateSummary()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get all positions for this agent's bots as initiator
|
||||
var positions = await _tradingService.GetPositionsByInitiatorIdentifiersAsync(_state.State.BotIds);
|
||||
|
||||
// Calculate aggregated statistics from position data
|
||||
var totalPnL = positions.Sum(p => p.ProfitAndLoss?.Realized ?? 0);
|
||||
var totalVolume = positions.Sum(p => p.Open.Price * p.Open.Quantity);
|
||||
var totalFees = positions.Sum(p => p.CalculateTotalFees());
|
||||
|
||||
// Calculate wins/losses from position PnL
|
||||
var totalWins = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) > 0);
|
||||
var totalLosses = positions.Count(p => (p.ProfitAndLoss?.Realized ?? 0) < 0);
|
||||
|
||||
// Calculate ROI based on total volume traded with proper division by zero handling
|
||||
var totalVolume = bots.Sum(b => b.Volume);
|
||||
decimal totalROI;
|
||||
|
||||
if (totalVolume > 0)
|
||||
@@ -148,11 +215,11 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
totalROI = 0;
|
||||
}
|
||||
|
||||
// Calculate Runtime based on the farthest date from bot startup times
|
||||
// Calculate Runtime based on the earliest position date
|
||||
DateTime? runtime = null;
|
||||
if (bots.Any())
|
||||
if (positions.Any())
|
||||
{
|
||||
runtime = bots.Max(b => b.StartupTime);
|
||||
runtime = positions.Min(p => p.Date);
|
||||
}
|
||||
|
||||
// Calculate total balance (USDC + open positions value)
|
||||
@@ -192,6 +259,10 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
totalBalance = 0; // Set to 0 if calculation fails
|
||||
}
|
||||
|
||||
// Get active strategies count from bot data (this is still needed for running bots)
|
||||
var bots = await _botService.GetBotsByIdsAsync(_state.State.BotIds);
|
||||
var activeStrategiesCount = bots.Count(b => b.Status == BotStatus.Running);
|
||||
|
||||
var summary = new AgentSummary
|
||||
{
|
||||
UserId = (int)this.GetPrimaryKeyLong(),
|
||||
@@ -201,13 +272,16 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
Losses = totalLosses,
|
||||
TotalROI = totalROI,
|
||||
Runtime = runtime,
|
||||
ActiveStrategiesCount = bots.Count(b => b.Status == BotStatus.Running),
|
||||
ActiveStrategiesCount = activeStrategiesCount,
|
||||
TotalVolume = totalVolume,
|
||||
TotalBalance = totalBalance,
|
||||
};
|
||||
|
||||
// Save summary to database
|
||||
await _agentService.SaveOrUpdateAgentSummary(summary);
|
||||
|
||||
_logger.LogDebug("Updated agent summary from position data for user {UserId}: PnL={PnL}, Volume={Volume}, Wins={Wins}, Losses={Losses}",
|
||||
this.GetPrimaryKeyLong(), totalPnL, totalVolume, totalWins, totalLosses);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -219,6 +293,10 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
{
|
||||
if (_state.State.BotIds.Add(botId))
|
||||
{
|
||||
// Update active strategies count
|
||||
_state.State.ActiveStrategiesCount = _state.State.BotIds.Count;
|
||||
_state.State.LastSummaryUpdate = DateTime.UtcNow;
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
_logger.LogInformation("Bot {BotId} registered to Agent {UserId}", botId, this.GetPrimaryKeyLong());
|
||||
|
||||
@@ -231,6 +309,10 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
{
|
||||
if (_state.State.BotIds.Remove(botId))
|
||||
{
|
||||
// Update active strategies count
|
||||
_state.State.ActiveStrategiesCount = _state.State.BotIds.Count;
|
||||
_state.State.LastSummaryUpdate = DateTime.UtcNow;
|
||||
|
||||
await _state.WriteStateAsync();
|
||||
_logger.LogInformation("Bot {BotId} unregistered from Agent {UserId}", botId, this.GetPrimaryKeyLong());
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Grains;
|
||||
using Managing.Application.Orleans;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -17,17 +16,14 @@ public class LiveBotRegistryGrain : Grain, ILiveBotRegistryGrain
|
||||
{
|
||||
private readonly IPersistentState<BotRegistryState> _state;
|
||||
private readonly ILogger<LiveBotRegistryGrain> _logger;
|
||||
private readonly IBotService _botService;
|
||||
|
||||
public LiveBotRegistryGrain(
|
||||
[PersistentState("bot-registry", "registry-store")]
|
||||
IPersistentState<BotRegistryState> state,
|
||||
ILogger<LiveBotRegistryGrain> logger,
|
||||
IBotService botService)
|
||||
ILogger<LiveBotRegistryGrain> logger)
|
||||
{
|
||||
_state = state;
|
||||
_logger = logger;
|
||||
_botService = botService;
|
||||
}
|
||||
|
||||
public override async Task OnActivateAsync(CancellationToken cancellationToken)
|
||||
@@ -196,8 +192,8 @@ public class LiveBotRegistryGrain : Grain, ILiveBotRegistryGrain
|
||||
{
|
||||
var platformGrain = GrainFactory.GetGrain<IPlatformSummaryGrain>("platform-summary");
|
||||
await platformGrain.UpdateActiveStrategyCountAsync(_state.State.ActiveBotsCount);
|
||||
|
||||
_logger.LogDebug("Notified platform summary about active strategy count change. New count: {ActiveCount}",
|
||||
|
||||
_logger.LogDebug("Notified platform summary about active strategy count change. New count: {ActiveCount}",
|
||||
_state.State.ActiveBotsCount);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
Reference in New Issue
Block a user