Enhance SpotBot logging and orphaned position handling
- Updated SpotBot to log detailed information when detecting small token balances, indicating potential gas reserves or dust. - Introduced a minimum threshold for orphaned positions, improving decision-making on whether to open new positions. - Enhanced logging for potential zombie positions, providing clearer warnings when token balances are missing. - Improved force close logging to clarify the status of remaining balances after attempts to clear them.
This commit is contained in:
@@ -180,13 +180,30 @@ public class SpotBot : TradingBotBase
|
||||
return false; // Don't allow opening new position until resolved
|
||||
}
|
||||
|
||||
if (tokenBalance is { Value: > 1m })
|
||||
if (tokenBalance is { Amount: > 0 })
|
||||
{
|
||||
// We have a token balance but no internal position - attempt to recover orphaned position
|
||||
// Check if this is a meaningful balance or just gas reserves / dust
|
||||
// Minimum threshold: $10 USD value to be considered an orphaned position
|
||||
const decimal minOrphanedBalanceValue = 10m;
|
||||
|
||||
if (tokenBalance.Value < minOrphanedBalanceValue)
|
||||
{
|
||||
await LogDebugAsync(
|
||||
$"ℹ️ Small Token Balance Detected (Likely Gas Reserve or Dust)\n" +
|
||||
$"Ticker: {Config.Ticker}\n" +
|
||||
$"Token balance: `{tokenBalance.Amount:F8}`\n" +
|
||||
$"USD Value: `${tokenBalance.Value:F2}`\n" +
|
||||
$"Below orphaned threshold of `${minOrphanedBalanceValue:F2}`\n" +
|
||||
$"Ignoring - safe to open new position");
|
||||
return true; // Safe to open new position - this is just dust/gas reserve
|
||||
}
|
||||
|
||||
// We have a significant token balance but no internal position - attempt to recover orphaned position
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Orphaned Token Balance Detected\n" +
|
||||
$"Ticker: {Config.Ticker}\n" +
|
||||
$"Token balance: `{tokenBalance.Amount:F5}`\n" +
|
||||
$"Token balance: `{tokenBalance.Amount:F5}` (Value: ${tokenBalance.Value:F2})\n" +
|
||||
$"Above orphaned threshold of `${minOrphanedBalanceValue:F2}`\n" +
|
||||
$"But no internal position tracked\n" +
|
||||
$"Attempting to recover position from database...");
|
||||
|
||||
@@ -198,7 +215,7 @@ public class SpotBot : TradingBotBase
|
||||
$"Could not recover orphaned position\n" +
|
||||
$"Manual cleanup may be required");
|
||||
}
|
||||
|
||||
|
||||
return false; // Don't allow opening new position until next cycle
|
||||
}
|
||||
|
||||
@@ -413,12 +430,17 @@ public class SpotBot : TradingBotBase
|
||||
|
||||
// Update quantity to match actual token balance
|
||||
var actualTokenBalance = tokenBalance.Amount;
|
||||
if (Math.Abs(internalPosition.Open.Quantity - actualTokenBalance) > 0.0001m)
|
||||
var quantityTolerance = internalPosition.Open.Quantity * 0.006m; // 0.6% tolerance for slippage
|
||||
var quantityDifference = Math.Abs(internalPosition.Open.Quantity - actualTokenBalance);
|
||||
|
||||
if (quantityDifference > quantityTolerance)
|
||||
{
|
||||
await LogDebugAsync(
|
||||
$"🔄 Token Balance Mismatch\n" +
|
||||
$"Internal Quantity: `{internalPosition.Open.Quantity:F5}`\n" +
|
||||
$"Broker Balance: `{actualTokenBalance:F5}`\n" +
|
||||
$"Difference: `{quantityDifference:F5}`\n" +
|
||||
$"Tolerance (0.6%): `{quantityTolerance:F5}`\n" +
|
||||
$"Updating to match broker balance");
|
||||
internalPosition.Open.Quantity = actualTokenBalance;
|
||||
positionForSignal.Open.Quantity = actualTokenBalance;
|
||||
@@ -478,10 +500,15 @@ public class SpotBot : TradingBotBase
|
||||
return;
|
||||
}
|
||||
|
||||
await LogDebugAsync(
|
||||
$"⚠️ Position Status Check\n" +
|
||||
$"Internal position `{internalPosition.Identifier}` shows Filled\n" +
|
||||
$"But no token balance found on broker or in history\n" +
|
||||
// Position is Filled but no token balance and not found in history
|
||||
// This could be a zombie position - check if token balance exists via direct exchange call
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Potential Zombie Position Detected\n" +
|
||||
$"Position: `{internalPosition.Identifier}`\n" +
|
||||
$"Status: Filled\n" +
|
||||
$"Token balance: 0\n" +
|
||||
$"Not found in exchange history\n" +
|
||||
$"This position may have been closed externally or data is delayed\n" +
|
||||
$"Will retry verification on next cycle");
|
||||
}
|
||||
}
|
||||
@@ -1089,8 +1116,10 @@ public class SpotBot : TradingBotBase
|
||||
{
|
||||
try
|
||||
{
|
||||
// Prevent infinite retry loop - only attempt force close once
|
||||
// The next bot cycle will handle verification
|
||||
await LogInformationAsync(
|
||||
$"🔄 Force Closing Remaining Balance\n" +
|
||||
$"🔄 Force Closing Remaining Balance (One-Time Attempt)\n" +
|
||||
$"Position: `{position.Identifier}`\n" +
|
||||
$"Ticker: {Config.Ticker}\n" +
|
||||
$"Remaining Balance: `{remainingBalance:F5}`");
|
||||
@@ -1127,7 +1156,7 @@ public class SpotBot : TradingBotBase
|
||||
$"Cleared Balance: `{remainingBalance:F5}`\n" +
|
||||
$"Close Price: `${currentPrice:F2}`");
|
||||
|
||||
// Verify one more time that balance is now cleared
|
||||
// Verify one more time that balance is now cleared (without triggering another force close)
|
||||
await Task.Delay(2000); // Wait for swap to complete
|
||||
|
||||
var finalBalance = await ServiceScopeHelpers.WithScopedService<IExchangeService, Balance?>(
|
||||
@@ -1137,15 +1166,16 @@ public class SpotBot : TradingBotBase
|
||||
if (finalBalance is { Amount: > 0.0001m })
|
||||
{
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Balance Still Remaining After Retry\n" +
|
||||
$"⚠️ Balance Still Remaining After Force Close Attempt\n" +
|
||||
$"Position: `{position.Identifier}`\n" +
|
||||
$"Remaining: `{finalBalance.Amount:F5}`\n" +
|
||||
$"Manual intervention may be required");
|
||||
$"This will be handled on the next bot cycle\n" +
|
||||
$"Manual intervention may be required if issue persists");
|
||||
}
|
||||
else
|
||||
{
|
||||
await LogInformationAsync(
|
||||
$"✅ Balance Fully Cleared After Retry\n" +
|
||||
$"✅ Balance Fully Cleared After Force Close\n" +
|
||||
$"Position: `{position.Identifier}`\n" +
|
||||
$"Final Balance: `{finalBalance?.Amount ?? 0:F5}`");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user