diff --git a/src/Managing.Application/Abstractions/IBotService.cs b/src/Managing.Application/Abstractions/IBotService.cs index f246d54d..27615e98 100644 --- a/src/Managing.Application/Abstractions/IBotService.cs +++ b/src/Managing.Application/Abstractions/IBotService.cs @@ -25,7 +25,7 @@ public interface IBotService Task> GetBotConfigsByIdsAsync(IEnumerable botIds); Task UpdateBotStatisticsAsync(Guid identifier); Task SaveBotStatisticsAsync(Bot bot); - + /// /// Computes the remaining available USDC allocation for the provided account, /// subtracting the sum of BotTradingBalance from other bots using the same account. @@ -35,7 +35,7 @@ public interface IBotService /// Bot identifier to exclude from allocation sum. /// Available USDC amount that can be allocated. Task GetAvailableAllocationUsdAsync(Account account, Guid excludeIdentifier = default); - + /// /// Gets paginated bots with filtering and sorting /// diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index 1e2ba4e7..d902677d 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -111,7 +111,7 @@ namespace Managing.Application.ManageBot var botConfig = await botGrain.GetConfiguration(); var account = await ServiceScopeHelpers.WithScopedService( _scopeFactory, - async accountService => await accountService.GetAccount(botConfig.AccountName, true, false)); + async accountService => await accountService.GetAccount(botConfig.AccountName, true, true)); if (account.Exchange == TradingExchanges.Evm || account.Exchange == TradingExchanges.GmxV2) { @@ -219,7 +219,7 @@ namespace Managing.Application.ManageBot public async Task> GetBotConfigsByIdsAsync(IEnumerable botIds) { var configs = new List(); - + foreach (var botId in botIds) { try @@ -234,7 +234,7 @@ namespace Managing.Application.ManageBot // Continue with other bots even if one fails } } - + return configs; } @@ -378,7 +378,8 @@ namespace Managing.Application.ManageBot } } - public async Task GetAvailableAllocationUsdAsync(Account account, Guid excludeIdentifier = default) + public async Task GetAvailableAllocationUsdAsync(Account account, + Guid excludeIdentifier = default) { try { @@ -387,40 +388,44 @@ namespace Managing.Application.ManageBot async repo => { // Get all bots for the account's user - var botsForUser = await repo.GetBotsByUserIdAsync(account.User.Id); + var botsForUser = (await repo.GetBotsByUserIdAsync(account.User.Id)).ToList(); // Sum allocations for bots using this account name, excluding the requested identifier - decimal totalAllocatedForAccount = 0m; - foreach (var bot in botsForUser) + var totalAllocatedForAccount = 0m; + var usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString()); + + if (botsForUser.Any()) { - if (excludeIdentifier != default && bot.Identifier == excludeIdentifier) + foreach (var bot in botsForUser) { - continue; - } + if (excludeIdentifier != default && bot.Identifier == excludeIdentifier) + { + continue; + } - var grain = _grainFactory.GetGrain(bot.Identifier); - TradingBotConfig config; - try - { - config = await grain.GetConfiguration(); - } - catch - { - continue; - } + var grain = _grainFactory.GetGrain(bot.Identifier); + TradingBotConfig config; + try + { + config = await grain.GetConfiguration(); + } + catch + { + continue; + } - if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase)) - { - totalAllocatedForAccount += config.BotTradingBalance; + if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase)) + { + totalAllocatedForAccount += config.BotTradingBalance; + } } } + else + { + totalAllocatedForAccount = usdcBalance?.Value ?? 0m; + } - // Current USDC balance for the account - var balances = await ServiceScopeHelpers.WithScopedService>( - _scopeFactory, async exchangeService => await exchangeService.GetBalances(account)); - var usdc = balances.FirstOrDefault(b => b.TokenName?.ToUpper() == "USDC"); - var usdcValue = usdc?.Value ?? 0m; - + var usdcValue = usdcBalance?.Value ?? 0m; var available = usdcValue - totalAllocatedForAccount; return available < 0m ? 0m : available; }); diff --git a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs index 45fcc4e2..24853d06 100644 --- a/src/Managing.Application/ManageBot/StartBotCommandHandler.cs +++ b/src/Managing.Application/ManageBot/StartBotCommandHandler.cs @@ -3,6 +3,7 @@ using Managing.Application.Abstractions.Grains; using Managing.Application.Abstractions.Services; using Managing.Application.ManageBot.Commands; using Managing.Common; +using Managing.Domain.Accounts; using MediatR; using static Managing.Common.Enums; @@ -42,7 +43,7 @@ namespace Managing.Application.ManageBot $"Bot trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}"); } - var account = await _accountService.GetAccount(request.Config.AccountName, true, false); + var account = await _accountService.GetAccount(request.Config.AccountName, true, true); if (account == null) { @@ -59,16 +60,18 @@ namespace Managing.Application.ManageBot } } + Balance usdcBalance = null; // For other exchanges, keep the original USDC balance check if (account.Exchange != TradingExchanges.Evm && account.Exchange != TradingExchanges.GmxV2) { - var usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString()); + usdcBalance = account.Balances.FirstOrDefault(b => b.TokenName == Ticker.USDC.ToString()); if (usdcBalance == null || usdcBalance.Value < Constants.GMX.Config.MinimumPositionAmount || usdcBalance.Value < request.Config.BotTradingBalance) { - throw new Exception($"Account {request.Config.AccountName} has no USDC balance or not enough balance"); + throw new Exception( + $"Account {request.Config.AccountName} has no USDC balance or not enough balance"); } } @@ -77,14 +80,15 @@ namespace Managing.Application.ManageBot if (request.Config.BotTradingBalance > availableAllocation) { throw new InvalidOperationException( - $"Insufficient available allocation on account '{account.Name}'. Requested: {request.Config.BotTradingBalance:F2} USDC, Available: {availableAllocation:F2} USDC."); + $"Insufficient available allocation on account '{account.Name}'. Requested: {request.Config.BotTradingBalance:F2} USDC, " + + $"Balance : {usdcBalance?.Value:F2 ?? 0} Available: {availableAllocation:F2} USDC."); } try { var botGrain = _grainFactory.GetGrain(Guid.NewGuid()); await botGrain.CreateAsync(request.Config, request.User); - + // Only start the bot if createOnly is false if (!request.CreateOnly) { diff --git a/src/Managing.WebApp/src/pages/dashboardPage/platformSummary.tsx b/src/Managing.WebApp/src/pages/dashboardPage/platformSummary.tsx index 6676eb28..853aced2 100644 --- a/src/Managing.WebApp/src/pages/dashboardPage/platformSummary.tsx +++ b/src/Managing.WebApp/src/pages/dashboardPage/platformSummary.tsx @@ -150,7 +150,7 @@ function PlatformSummary({index}: { index: number }) { {/* Main Stats Grid */} -
+
{/* Total Volume Traded */}

Total Volume Traded

@@ -319,7 +319,7 @@ function PlatformSummary({index}: { index: number }) {
{/* Platform Summary Stats */} -
+

Total Agents

@@ -367,10 +367,7 @@ function PlatformSummary({index}: { index: number }) { {changesToday.openInterestChange >= 0 ? '+' : ''}{formatCurrency(changesToday.openInterestChange)} Today
-
- {/* Position Metrics */} -

Total Positions

@@ -415,6 +412,11 @@ function PlatformSummary({index}: { index: number }) {
+ {/* Position Metrics */} +
+ +
+ {/* Platform Metrics Chart */}