Add Agent tracking balance
This commit is contained in:
@@ -1,52 +1,67 @@
|
||||
using Managing.Application.Abstractions;
|
||||
using Managing.Application.Abstractions.Repositories;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.ManageBot.Commands;
|
||||
using Managing.Application.Workers.Abstractions;
|
||||
using Managing.Domain.Statistics;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.Workers;
|
||||
|
||||
public class BalanceTrackingWorker : BackgroundService
|
||||
public class BalanceTrackingWorker : BaseWorker<BalanceTrackingWorker>
|
||||
{
|
||||
private readonly ILogger<BalanceTrackingWorker> _logger;
|
||||
private readonly IMediator _mediator;
|
||||
private readonly IAccountService _accountService;
|
||||
private readonly TimeSpan _interval = TimeSpan.FromMinutes(1);
|
||||
private readonly IAgentBalanceRepository _agentBalanceRepository;
|
||||
private bool _isInitialized;
|
||||
|
||||
public BalanceTrackingWorker(
|
||||
ILogger<BalanceTrackingWorker> logger,
|
||||
IMediator mediator,
|
||||
IAccountService accountService)
|
||||
IAccountService accountService,
|
||||
IAgentBalanceRepository agentBalanceRepository,
|
||||
IWorkerService workerService)
|
||||
: base(
|
||||
WorkerType.BalanceTracking,
|
||||
logger,
|
||||
TimeSpan.FromHours(1),
|
||||
workerService)
|
||||
{
|
||||
_logger = logger;
|
||||
_mediator = mediator;
|
||||
_accountService = accountService;
|
||||
_agentBalanceRepository = agentBalanceRepository;
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
protected override async Task Run(CancellationToken cancellationToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
if (!_isInitialized)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Starting balance tracking...");
|
||||
await TrackBalances();
|
||||
_logger.LogInformation("Completed balance tracking");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error occurred while tracking balances");
|
||||
}
|
||||
|
||||
await Task.Delay(_interval, stoppingToken);
|
||||
_logger.LogInformation("Waiting 5 minutes for bots to initialize before starting balance tracking...");
|
||||
await Task.Delay(TimeSpan.FromMinutes(3), cancellationToken);
|
||||
_isInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TrackBalances()
|
||||
{
|
||||
_logger.LogInformation("Starting balance tracking...");
|
||||
|
||||
// Get all active bots
|
||||
var bots = await _mediator.Send(new GetActiveBotsCommand());
|
||||
|
||||
|
||||
if (bots.Count == 0)
|
||||
{
|
||||
_logger.LogWarning("No active bots found. Skipping balance tracking.");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Found {bots.Count} active bots. Proceeding with balance tracking.");
|
||||
await TrackBalances(bots);
|
||||
_logger.LogInformation("Completed balance tracking");
|
||||
}
|
||||
|
||||
private async Task TrackBalances(List<ITradingBot> bots)
|
||||
{
|
||||
// Group bots by agent/user
|
||||
var botsByAgent = bots
|
||||
.Where(b => b.User != null)
|
||||
@@ -59,8 +74,25 @@ public class BalanceTrackingWorker : BackgroundService
|
||||
{
|
||||
var agentName = agentEntry.Key;
|
||||
var agentBots = agentEntry.Value;
|
||||
|
||||
// Check if we need to update this agent's balance
|
||||
var lastBalance = (await _agentBalanceRepository.GetAgentBalances(
|
||||
agentName,
|
||||
DateTime.UtcNow.AddDays(-1),
|
||||
DateTime.UtcNow)).OrderByDescending(b => b.Time).FirstOrDefault();
|
||||
|
||||
if (lastBalance != null && DateTime.UtcNow.Subtract(lastBalance.Time).TotalHours < 24)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
$"Skipping agent {agentName} - Last balance update was {lastBalance.Time:g} UTC");
|
||||
continue;
|
||||
}
|
||||
|
||||
decimal totalAgentValue = 0;
|
||||
decimal totalBotAllocatedBalance = 0;
|
||||
decimal totalAccountUsdValue = 0;
|
||||
decimal botsAllocationUsdValue = 0;
|
||||
decimal totalPnL = 0;
|
||||
|
||||
_logger.LogInformation($"Processing agent: {agentName} with {agentBots.Count} bots");
|
||||
|
||||
@@ -80,7 +112,7 @@ public class BalanceTrackingWorker : BackgroundService
|
||||
if (accountBalance.Balances != null)
|
||||
{
|
||||
var accountTotalValue = accountBalance.Balances.Sum(b => b.Value);
|
||||
|
||||
|
||||
// If this is the account that holds the bot balances (USDC), subtract the allocated amounts
|
||||
var usdcBalance = accountBalance.Balances.FirstOrDefault(b => b.TokenName == "USDC");
|
||||
if (usdcBalance != null)
|
||||
@@ -92,11 +124,11 @@ public class BalanceTrackingWorker : BackgroundService
|
||||
$"Account {accountBalance.Name} USDC balance after bot allocation: {usdcBalance.Value} USD");
|
||||
}
|
||||
|
||||
totalAgentValue += accountTotalValue;
|
||||
totalAccountUsdValue += accountTotalValue;
|
||||
|
||||
_logger.LogInformation(
|
||||
$"Account {accountBalance.Name} total value: {accountTotalValue} USD");
|
||||
|
||||
|
||||
// Log individual token balances for debugging
|
||||
foreach (var balance in accountBalance.Balances)
|
||||
{
|
||||
@@ -106,25 +138,42 @@ public class BalanceTrackingWorker : BackgroundService
|
||||
}
|
||||
}
|
||||
|
||||
// Add up all bot wallet balances for this agent
|
||||
// Process all bots in a single iteration
|
||||
foreach (var bot in agentBots)
|
||||
{
|
||||
// Get wallet balance
|
||||
var latestBotBalance = bot.WalletBalances
|
||||
.OrderByDescending(x => x.Key)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (latestBotBalance.Key != default)
|
||||
{
|
||||
totalAgentValue += latestBotBalance.Value;
|
||||
botsAllocationUsdValue += latestBotBalance.Value;
|
||||
_logger.LogInformation(
|
||||
$"Bot {bot.Name} wallet balance: {latestBotBalance.Value} USD at {latestBotBalance.Key}");
|
||||
}
|
||||
|
||||
// Calculate PnL
|
||||
totalPnL += bot.GetProfitAndLoss();
|
||||
}
|
||||
|
||||
totalAgentValue = totalAccountUsdValue + botsAllocationUsdValue;
|
||||
|
||||
_logger.LogInformation(
|
||||
$"Agent {agentName} total aggregated value: {totalAgentValue} USD");
|
||||
|
||||
// TODO: Save aggregated agent balance to database
|
||||
$"Agent {agentName} total aggregated value: {totalAgentValue} USD (Account: {totalAccountUsdValue} USD, Bot Wallet: {botsAllocationUsdValue} USD)");
|
||||
|
||||
// Create and save the agent balance
|
||||
var agentBalance = new AgentBalance
|
||||
{
|
||||
AgentName = agentName,
|
||||
TotalValue = totalAgentValue,
|
||||
TotalAccountUsdValue = totalAccountUsdValue,
|
||||
BotsAllocationUsdValue = botsAllocationUsdValue,
|
||||
PnL = totalPnL,
|
||||
Time = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_agentBalanceRepository.InsertAgentBalance(agentBalance);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
23
src/Managing.Application/Workers/BotManagerWorker.cs
Normal file
23
src/Managing.Application/Workers/BotManagerWorker.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Managing.Application.ManageBot;
|
||||
using Managing.Application.Workers.Abstractions;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.Workers;
|
||||
|
||||
public class BotManagerWorker(
|
||||
ILogger<BotManagerWorker> logger,
|
||||
IMediator mediadior,
|
||||
IWorkerService workerService)
|
||||
: BaseWorker<BotManagerWorker>(WorkerType.BotManager,
|
||||
logger,
|
||||
TimeSpan.FromMinutes(5),
|
||||
workerService)
|
||||
{
|
||||
protected override async Task Run(CancellationToken cancellationToken)
|
||||
{
|
||||
var loadBackupBotCommand = new LoadBackupBotCommand();
|
||||
await mediadior.Send(loadBackupBotCommand, cancellationToken);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user