Do not stop strategy if position open
This commit is contained in:
@@ -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();
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,7 @@ namespace Managing.Application.Bots.Models
|
||||
SwapCooldownActive,
|
||||
BalanceFetchError,
|
||||
SwapExecutionError,
|
||||
InsufficientEthBelowMinimum
|
||||
InsufficientEthBelowMinimum,
|
||||
BotsHaveOpenPositions
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user