Implement spot position history retrieval in SpotBot and related services
- Added CheckSpotPositionInExchangeHistory method to SpotBot for verifying closed positions against exchange history. - Enhanced logging for Web3Proxy errors during position verification. - Introduced GetSpotPositionHistory method in IEvmManager, IExchangeService, and IWeb3ProxyService interfaces. - Implemented GetSpotPositionHistory in EvmManager and ExchangeService to fetch historical swap data. - Updated GMX SDK integration to support fetching spot position history. - Modified generated API types to include new trading type and position history structures.
This commit is contained in:
@@ -337,11 +337,31 @@ public class SpotBot : TradingBotBase, ITradingBot
|
||||
// No token balance found - check if position was closed
|
||||
if (internalPosition.Status == PositionStatus.Filled)
|
||||
{
|
||||
var (positionFoundInHistory, hadWeb3ProxyError) =
|
||||
await CheckSpotPositionInExchangeHistory(internalPosition);
|
||||
|
||||
if (hadWeb3ProxyError)
|
||||
{
|
||||
await LogWarningAsync(
|
||||
$"⏳ Web3Proxy Error During Spot Position Verification\n" +
|
||||
$"Position: `{internalPosition.Identifier}`\n" +
|
||||
$"Cannot verify if position is closed\n" +
|
||||
$"Will retry on next execution cycle");
|
||||
return;
|
||||
}
|
||||
|
||||
if (positionFoundInHistory)
|
||||
{
|
||||
internalPosition.Status = PositionStatus.Finished;
|
||||
await HandleClosedPosition(internalPosition);
|
||||
return;
|
||||
}
|
||||
|
||||
await LogDebugAsync(
|
||||
$"⚠️ Position Status Check\n" +
|
||||
$"Internal position `{internalPosition.Identifier}` shows Filled\n" +
|
||||
$"But no token balance found on broker\n" +
|
||||
$"Position may have been closed");
|
||||
$"But no token balance found on broker or in history\n" +
|
||||
$"Will retry verification on next cycle");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,6 +371,56 @@ public class SpotBot : TradingBotBase, ITradingBot
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<(bool found, bool hadError)> CheckSpotPositionInExchangeHistory(Position position)
|
||||
{
|
||||
try
|
||||
{
|
||||
await LogDebugAsync(
|
||||
$"🔍 Checking Spot Position History for Position: `{position.Identifier}`\nTicker: `{Config.Ticker}`");
|
||||
|
||||
List<Position> positionHistory = null;
|
||||
await ServiceScopeHelpers.WithScopedService<IExchangeService>(_scopeFactory,
|
||||
async exchangeService =>
|
||||
{
|
||||
var fromDate = DateTime.UtcNow.AddHours(-24);
|
||||
var toDate = DateTime.UtcNow;
|
||||
positionHistory =
|
||||
await exchangeService.GetSpotPositionHistory(Account, Config.Ticker, fromDate, toDate);
|
||||
});
|
||||
|
||||
if (positionHistory != null && positionHistory.Any())
|
||||
{
|
||||
var recentPosition = positionHistory
|
||||
.OrderByDescending(p => p.Date)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (recentPosition != null)
|
||||
{
|
||||
await LogDebugAsync(
|
||||
$"✅ Spot Position Found in History\n" +
|
||||
$"Position: `{position.Identifier}`\n" +
|
||||
$"Ticker: `{recentPosition.Ticker}`\n" +
|
||||
$"Date: `{recentPosition.Date}`");
|
||||
return (true, false);
|
||||
}
|
||||
}
|
||||
|
||||
await LogDebugAsync(
|
||||
$"❌ No Spot Position Found in Exchange History\nPosition: `{position.Identifier}`\nPosition may still be open or data is delayed");
|
||||
return (false, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError(ex, "Error checking spot position history for position {PositionId}", position.Identifier);
|
||||
await LogWarningAsync(
|
||||
$"⚠️ Web3Proxy Error During Spot Position History Check\n" +
|
||||
$"Position: `{position.Identifier}`\n" +
|
||||
$"Error: {ex.Message}\n" +
|
||||
$"Will retry on next execution cycle");
|
||||
return (false, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task HandleOrderManagementAndPositionStatus(LightSignal signal, Position internalPosition,
|
||||
Position positionForSignal)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user