Add balance tracking on bot start/restart; implement TrackBalanceOnBotStartAsync in IAgentGrain and AgentGrain, and trigger it in LiveTradingBotGrain. Enhance logging for balance tracking operations.

This commit is contained in:
2025-12-26 15:43:46 +07:00
parent f884cb2362
commit 7a3ede03ca
4 changed files with 117 additions and 9 deletions

View File

@@ -67,5 +67,12 @@ namespace Managing.Application.Abstractions.Grains
/// </summary>
[OneWay]
Task ForceUpdateSummary();
/// <summary>
/// Triggers balance tracking data insertion when a bot starts/restarts.
/// This captures the balance change related to botsAllocationUsdValue.
/// </summary>
[OneWay]
Task TrackBalanceOnBotStartAsync();
}
}

View File

@@ -665,4 +665,94 @@ public class AgentGrain : Grain, IAgentGrain
(int)this.GetPrimaryKeyLong());
}
}
/// <summary>
/// Triggers balance tracking data insertion when a bot starts/restarts.
/// This captures the balance change related to botsAllocationUsdValue.
/// </summary>
[OneWay]
public async Task TrackBalanceOnBotStartAsync()
{
try
{
_logger.LogInformation("Tracking balance on bot start/restart for user {UserId}", this.GetPrimaryKeyLong());
// Get all positions for this agent's bots as initiator
var positions = (await _tradingService.GetPositionByUserIdAsync((int)this.GetPrimaryKeyLong()))
.Where(p => p.IsValidForMetrics()).ToList();
var metrics = TradingBox.CalculateAgentSummaryMetrics(positions);
// Calculate total balance (USDC wallet + USDC in open positions value)
decimal totalBalance = 0;
decimal usdcWalletValue = 0;
decimal usdcInPositionsValue = 0;
try
{
var userId = (int)this.GetPrimaryKeyLong();
var user = await _userService.GetUserByIdAsync(userId);
var userAccounts = await _accountService.GetAccountsByUserAsync(user, hideSecrets: true, true);
foreach (var account in userAccounts)
{
// Get USDC balance
var usdcBalances = await GetOrRefreshBalanceDataAsync(account.Name);
var usdcBalance = usdcBalances?.UsdcValue ?? 0;
usdcWalletValue += usdcBalance;
}
foreach (var position in positions.Where(p => p.IsOpen()))
{
var positionUsd = position.Open.Price * position.Open.Quantity;
var net = position.ProfitAndLoss?.Net ?? 0;
usdcInPositionsValue += positionUsd + net;
}
totalBalance = usdcWalletValue + usdcInPositionsValue;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error calculating total balance for agent {UserId} during bot start tracking",
this.GetPrimaryKeyLong());
totalBalance = 0; // Set to 0 if calculation fails
usdcWalletValue = 0;
usdcInPositionsValue = 0;
}
// Get active strategies to calculate botsAllocationUsdValue
var activeStrategies = await ServiceScopeHelpers.WithScopedService<IBotService, List<Bot>>(_scopeFactory,
async (botService) =>
{
return (await botService.GetBotsByUser((int)this.GetPrimaryKeyLong()))
.Where(b => b.Status == BotStatus.Running)
.ToList();
});
var botsAllocationUsdValue = 0m;
if (activeStrategies.Any())
{
// Calculate bots allocation USD value from bot configurations
var botIds = activeStrategies.Select(b => b.Identifier);
var botConfigs =
await ServiceScopeHelpers.WithScopedService<IBotService, IEnumerable<TradingBotConfig>>(
_scopeFactory,
async (botService) => { return await botService.GetBotConfigsByIdsAsync(botIds); });
botsAllocationUsdValue = botConfigs.Sum(config => config.BotTradingBalance);
}
// Insert balance tracking data
InsertBalanceTrackingData(totalBalance, botsAllocationUsdValue, metrics.NetPnL, usdcWalletValue,
usdcInPositionsValue);
_logger.LogInformation(
"Balance tracking completed on bot start/restart for user {UserId}: TotalBalance={TotalBalance}, BotsAllocation={BotsAllocation}, NetPnL={NetPnL}",
this.GetPrimaryKeyLong(), totalBalance, botsAllocationUsdValue, metrics.NetPnL);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error tracking balance on bot start/restart for user {UserId}",
this.GetPrimaryKeyLong());
}
}
}

View File

@@ -247,6 +247,24 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
await SaveBotAsync(BotStatus.Running);
await UpdateBotRegistryStatus(BotStatus.Running);
// Trigger balance tracking since we now have a balance change related to botsAllocationUsdValue
if (_state.State.User != null)
{
try
{
var agentGrain = GrainFactory.GetGrain<IAgentGrain>(_state.State.User.Id);
await agentGrain.TrackBalanceOnBotStartAsync();
}
catch (Exception ex)
{
_logger.LogWarning(ex,
"Failed to track balance on bot start for LiveTradingBotGrain {GrainId}, but bot started successfully",
this.GetPrimaryKey());
SentrySdk.CaptureException(ex);
// Don't throw - bot started successfully, balance tracking is non-critical
}
}
_logger.LogInformation("LiveTradingBotGrain {GrainId} resumed successfully", this.GetPrimaryKey());
}
catch (Exception ex)

View File

@@ -109,18 +109,11 @@ public abstract class TradingBotBase : ITradingBot
break;
case BotStatus.Running:
case BotStatus.Stopped:
return;
case BotStatus.Stopped:
// If status was Stopped we log a message to inform the user that the bot is restarting
await LogInformationAsync($"🔄 Bot Restarted\n" +
$"📊 Resuming operations with {Signals.Count} signals and {Positions.Count} positions\n" +
$"✅ Ready to continue trading");
break;
default:
// Handle any other status if needed
break;
return;
}
}
catch (Exception ex)