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

@@ -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());
}
}
}