From 6134364ddd40d2bf87f98a05b0b911e3d7f1aa0e Mon Sep 17 00:00:00 2001 From: cryptooda Date: Mon, 5 Jan 2026 23:21:51 +0700 Subject: [PATCH] Enhance SpotBot balance management after position closure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added logic to wait for ETH→USDC swap to settle before refreshing the USDC balance, preventing premature bot stoppage due to low balance. - Implemented balance verification and cache invalidation for accurate balance checks post-swap. - Improved logging to indicate the status of balance refresh and cache invalidation after closing a position. --- src/Managing.Application/Bots/SpotBot.cs | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Managing.Application/Bots/SpotBot.cs b/src/Managing.Application/Bots/SpotBot.cs index 01c8827e..f0708946 100644 --- a/src/Managing.Application/Bots/SpotBot.cs +++ b/src/Managing.Application/Bots/SpotBot.cs @@ -1105,6 +1105,31 @@ public class SpotBot : TradingBotBase await VerifyTokenBalanceCleared(closedPosition); } + // Wait for swap to settle and refresh USDC balance + // This prevents the bot from stopping due to "low USDC" before the ETH→USDC swap completes + if (!Config.IsForWatchingOnly && Config.TradingType != TradingType.BacktestSpot) + { + await LogDebugAsync( + $"⏳ Waiting for swap to settle and refreshing USDC balance...\n" + + $"Position: `{closedPosition.Identifier}`"); + + // Wait 3 seconds for the swap to settle on-chain + await Task.Delay(3000); + + // Refresh USDC balance to reflect the swapped tokens + await VerifyAndUpdateBalanceAsync(); + + // Invalidate AgentGrain balance cache to force fresh fetch on next balance check + // This ensures the bot won't stop due to "low USDC" using stale cached data + await ServiceScopeHelpers.WithScopedService(_scopeFactory, async grainFactory => + { + var agentGrain = grainFactory.GetGrain(Account.User.Id); + await agentGrain.ForceUpdateSummaryImmediate(); + }); + + await LogDebugAsync($"✅ Balance refreshed and cache invalidated after position close"); + } + if (tradeClosingPosition) { await SetPositionStatus(signal.Identifier, PositionStatus.Finished);