Do not stop strategy if position open

This commit is contained in:
2025-10-01 12:31:53 +07:00
parent 5953b96a38
commit 3e680ab815
4 changed files with 103 additions and 1 deletions

View File

@@ -46,4 +46,10 @@ public interface ILiveTradingBotGrain : IGrainWithGuidKey
/// Returns true if the ping was successful, false otherwise
/// </summary>
Task<bool> PingAsync();
/// <summary>
/// Checks if the bot has any open positions
/// Returns true if there are open positions, false otherwise
/// </summary>
Task<bool> HasOpenPositionsAsync();
}

View File

@@ -388,6 +388,22 @@ public class AgentGrain : Grain, IAgentGrain
};
}
// Check if any bot has open positions before executing autoswap
var hasOpenPositions = await HasAnyBotWithOpenPositionsAsync();
if (hasOpenPositions)
{
_logger.LogWarning(
"Cannot execute autoswap - ETH: {EthValue:F2} USD, USDC: {UsdcValue:F2} USD (bots have open positions)",
balanceData.EthValueInUsd, balanceData.UsdcValue);
return new BalanceCheckResult
{
IsSuccessful = false,
FailureReason = BalanceCheckFailureReason.BotsHaveOpenPositions,
Message = "Cannot execute autoswap while bots have open positions",
ShouldStopBot = false // Don't stop the bot, just skip this execution cycle
};
}
// Mark swap as in progress
_state.State.IsSwapInProgress = true;
await _state.WriteStateAsync();
@@ -472,6 +488,55 @@ public class AgentGrain : Grain, IAgentGrain
}
}
/// <summary>
/// Checks if any of the user's bots have open positions
/// </summary>
private async Task<bool> HasAnyBotWithOpenPositionsAsync()
{
try
{
// Get all bot IDs for this user from the registry
var botRegistry = GrainFactory.GetGrain<ILiveBotRegistryGrain>(0);
var userBots = await botRegistry.GetBotsForUser((int)this.GetPrimaryKeyLong());
if (!userBots.Any())
{
_logger.LogDebug("No bots found for user {UserId}", this.GetPrimaryKeyLong());
return false;
}
// Check each bot for open positions
foreach (var botEntry in userBots)
{
try
{
var botGrain = GrainFactory.GetGrain<ILiveTradingBotGrain>(botEntry.Identifier);
var hasOpenPositions = await botGrain.HasOpenPositionsAsync();
if (hasOpenPositions)
{
_logger.LogInformation("Bot {BotId} has open positions, blocking autoswap for user {UserId}",
botEntry.Identifier, this.GetPrimaryKeyLong());
return true;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error checking open positions for bot {BotId}, skipping", botEntry.Identifier);
// Continue checking other bots even if one fails
}
}
_logger.LogDebug("No bots with open positions found for user {UserId}", this.GetPrimaryKeyLong());
return false;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking for open positions across all bots for user {UserId}", this.GetPrimaryKeyLong());
return false; // Default to false on error to avoid blocking autoswap
}
}
/// <summary>
/// Gets cached balance data or fetches fresh data if cache is invalid/expired
/// </summary>

View File

@@ -835,4 +835,34 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
return Task.FromResult(false);
}
}
/// <summary>
/// Checks if the bot has any open positions
/// Returns true if there are open positions, false otherwise
/// </summary>
public Task<bool> HasOpenPositionsAsync()
{
try
{
if (_tradingBot == null)
{
// For non-running bots, check grain state positions
var hasOpenPositions = _state.State.Positions?.Values.Any(p => !p.IsFinished()) ?? false;
_logger.LogDebug("Bot {GrainId} has open positions: {HasOpenPositions} (from grain state)",
this.GetPrimaryKey(), hasOpenPositions);
return Task.FromResult(hasOpenPositions);
}
// For running bots, check live positions
var hasLiveOpenPositions = _tradingBot.Positions?.Values.Any(p => !p.IsFinished()) ?? false;
_logger.LogDebug("Bot {GrainId} has open positions: {HasOpenPositions} (from live data)",
this.GetPrimaryKey(), hasLiveOpenPositions);
return Task.FromResult(hasLiveOpenPositions);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error checking open positions for LiveTradingBotGrain {GrainId}", this.GetPrimaryKey());
return Task.FromResult(false); // Default to false on error to avoid blocking autoswap
}
}
}

View File

@@ -111,6 +111,7 @@ namespace Managing.Application.Bots.Models
SwapCooldownActive,
BalanceFetchError,
SwapExecutionError,
InsufficientEthBelowMinimum
InsufficientEthBelowMinimum,
BotsHaveOpenPositions
}
}