Fix allocated amount when no bot

This commit is contained in:
2025-10-05 01:00:47 +07:00
parent 5468b1e7f7
commit 63683d6bdf
4 changed files with 52 additions and 41 deletions

View File

@@ -111,7 +111,7 @@ namespace Managing.Application.ManageBot
var botConfig = await botGrain.GetConfiguration(); var botConfig = await botGrain.GetConfiguration();
var account = await ServiceScopeHelpers.WithScopedService<IAccountService, Account>( var account = await ServiceScopeHelpers.WithScopedService<IAccountService, Account>(
_scopeFactory, _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) if (account.Exchange == TradingExchanges.Evm || account.Exchange == TradingExchanges.GmxV2)
{ {
@@ -378,7 +378,8 @@ namespace Managing.Application.ManageBot
} }
} }
public async Task<decimal> GetAvailableAllocationUsdAsync(Account account, Guid excludeIdentifier = default) public async Task<decimal> GetAvailableAllocationUsdAsync(Account account,
Guid excludeIdentifier = default)
{ {
try try
{ {
@@ -387,40 +388,44 @@ namespace Managing.Application.ManageBot
async repo => async repo =>
{ {
// Get all bots for the account's user // 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 // Sum allocations for bots using this account name, excluding the requested identifier
decimal totalAllocatedForAccount = 0m; var totalAllocatedForAccount = 0m;
foreach (var bot in botsForUser) 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<ILiveTradingBotGrain>(bot.Identifier); var grain = _grainFactory.GetGrain<ILiveTradingBotGrain>(bot.Identifier);
TradingBotConfig config; TradingBotConfig config;
try try
{ {
config = await grain.GetConfiguration(); config = await grain.GetConfiguration();
} }
catch catch
{ {
continue; continue;
} }
if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase)) if (string.Equals(config.AccountName, account.Name, StringComparison.OrdinalIgnoreCase))
{ {
totalAllocatedForAccount += config.BotTradingBalance; totalAllocatedForAccount += config.BotTradingBalance;
}
} }
} }
else
{
totalAllocatedForAccount = usdcBalance?.Value ?? 0m;
}
// Current USDC balance for the account var usdcValue = usdcBalance?.Value ?? 0m;
var balances = await ServiceScopeHelpers.WithScopedService<IExchangeService, IEnumerable<Balance>>(
_scopeFactory, async exchangeService => await exchangeService.GetBalances(account));
var usdc = balances.FirstOrDefault(b => b.TokenName?.ToUpper() == "USDC");
var usdcValue = usdc?.Value ?? 0m;
var available = usdcValue - totalAllocatedForAccount; var available = usdcValue - totalAllocatedForAccount;
return available < 0m ? 0m : available; return available < 0m ? 0m : available;
}); });

View File

@@ -3,6 +3,7 @@ using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Services; using Managing.Application.Abstractions.Services;
using Managing.Application.ManageBot.Commands; using Managing.Application.ManageBot.Commands;
using Managing.Common; using Managing.Common;
using Managing.Domain.Accounts;
using MediatR; using MediatR;
using static Managing.Common.Enums; using static Managing.Common.Enums;
@@ -42,7 +43,7 @@ namespace Managing.Application.ManageBot
$"Bot trading balance must be greater than {Constants.GMX.Config.MinimumPositionAmount}"); $"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) if (account == null)
{ {
@@ -59,16 +60,18 @@ namespace Managing.Application.ManageBot
} }
} }
Balance usdcBalance = null;
// For other exchanges, keep the original USDC balance check // For other exchanges, keep the original USDC balance check
if (account.Exchange != TradingExchanges.Evm && account.Exchange != TradingExchanges.GmxV2) 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 || if (usdcBalance == null ||
usdcBalance.Value < Constants.GMX.Config.MinimumPositionAmount || usdcBalance.Value < Constants.GMX.Config.MinimumPositionAmount ||
usdcBalance.Value < request.Config.BotTradingBalance) 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,7 +80,8 @@ namespace Managing.Application.ManageBot
if (request.Config.BotTradingBalance > availableAllocation) if (request.Config.BotTradingBalance > availableAllocation)
{ {
throw new InvalidOperationException( 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 try

View File

@@ -150,7 +150,7 @@ function PlatformSummary({index}: { index: number }) {
</div> </div>
{/* Main Stats Grid */} {/* Main Stats Grid */}
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-8"> <div className="grid grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
{/* Total Volume Traded */} {/* Total Volume Traded */}
<div className="bg-base-200 rounded-lg p-6"> <div className="bg-base-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-400 mb-2">Total Volume Traded</h3> <h3 className="text-lg font-semibold text-gray-400 mb-2">Total Volume Traded</h3>
@@ -319,7 +319,7 @@ function PlatformSummary({index}: { index: number }) {
</div> </div>
{/* Platform Summary Stats */} {/* Platform Summary Stats */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8"> <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-7 gap-6 mb-8">
<div className="bg-base-200 rounded-lg p-6"> <div className="bg-base-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-400 mb-2">Total Agents</h3> <h3 className="text-lg font-semibold text-gray-400 mb-2">Total Agents</h3>
<div className="text-3xl font-bold text-white mb-1"> <div className="text-3xl font-bold text-white mb-1">
@@ -367,10 +367,7 @@ function PlatformSummary({index}: { index: number }) {
{changesToday.openInterestChange >= 0 ? '+' : ''}{formatCurrency(changesToday.openInterestChange)} Today {changesToday.openInterestChange >= 0 ? '+' : ''}{formatCurrency(changesToday.openInterestChange)} Today
</div> </div>
</div> </div>
</div>
{/* Position Metrics */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div className="bg-base-200 rounded-lg p-6"> <div className="bg-base-200 rounded-lg p-6">
<h3 className="text-lg font-semibold text-gray-400 mb-2">Total Positions</h3> <h3 className="text-lg font-semibold text-gray-400 mb-2">Total Positions</h3>
<div className="text-3xl font-bold text-white mb-1"> <div className="text-3xl font-bold text-white mb-1">
@@ -415,6 +412,11 @@ function PlatformSummary({index}: { index: number }) {
</div> </div>
</div> </div>
{/* Position Metrics */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
</div>
{/* Platform Metrics Chart */} {/* Platform Metrics Chart */}
<div className="mb-8"> <div className="mb-8">
<PlatformLineChart <PlatformLineChart