Clean tradingbot and spot and future

This commit is contained in:
2025-12-11 14:10:38 +07:00
parent 292a48d108
commit df8c199cce
5 changed files with 32 additions and 61 deletions

View File

@@ -68,12 +68,6 @@ public class BacktestFuturesBot : TradingBotBase, ITradingBot
return position;
}
protected override async Task<List<Position>> GetBrokerPositionsForUpdate(Account account)
{
// In backtest mode, return empty list (no broker positions to check)
return new List<Position>();
}
protected override async Task UpdatePositionWithBrokerData(Position position, List<Position> brokerPositions)
{
// In backtest mode, skip broker synchronization
@@ -289,7 +283,8 @@ public class BacktestFuturesBot : TradingBotBase, ITradingBot
_scopeFactory, async (exchangeService, accountService, tradingService) =>
{
closedPosition =
await new CloseBacktestFuturesPositionCommandHandler(exchangeService, accountService, tradingService,
await new CloseBacktestFuturesPositionCommandHandler(exchangeService, accountService,
tradingService,
_scopeFactory)
.Handle(command);
});

View File

@@ -67,12 +67,6 @@ public class BacktestSpotBot : TradingBotBase, ITradingBot
return position;
}
protected override async Task<List<Position>> GetBrokerPositionsForUpdate(Account account)
{
// In backtest mode, return empty list (no broker positions to check)
return new List<Position>();
}
protected override async Task UpdatePositionWithBrokerData(Position position, List<Position> brokerPositions)
{
// In backtest mode, skip broker synchronization
@@ -247,7 +241,8 @@ public class BacktestSpotBot : TradingBotBase, ITradingBot
// Only LONG signals should reach here (SHORT signals are filtered out earlier)
if (signal.Direction != TradeDirection.Long)
{
throw new InvalidOperationException($"Only LONG signals can open positions in spot trading. Received: {signal.Direction}");
throw new InvalidOperationException(
$"Only LONG signals can open positions in spot trading. Received: {signal.Direction}");
}
if (Account == null || Account.User == null)
@@ -331,4 +326,3 @@ public class BacktestSpotBot : TradingBotBase, ITradingBot
}
}
}

View File

@@ -75,14 +75,6 @@ public class FuturesBot : TradingBotBase, ITradingBot
async tradingService => { return await tradingService.GetPositionByIdentifierAsync(position.Identifier); });
}
protected override async Task<List<Position>> GetBrokerPositionsForUpdate(Account account)
{
// For live trading, get real broker positions
return await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Position>>(
_scopeFactory,
async exchangeService => { return [.. await exchangeService.GetBrokerPositions(Account)]; });
}
protected override async Task UpdatePositionWithBrokerData(Position position, List<Position> brokerPositions)
{
// Live trading broker position synchronization logic is handled in the base UpdatePosition method
@@ -210,11 +202,16 @@ public class FuturesBot : TradingBotBase, ITradingBot
}
protected override async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal,
List<Position> brokerPositions)
protected override async Task SynchronizeWithBrokerPositions(
Position internalPosition,
Position positionForSignal)
{
var liveBrokerPositions = await ServiceScopeHelpers.WithScopedService<IExchangeService, List<Position>>(
_scopeFactory,
async exchangeService => [.. await exchangeService.GetBrokerPositions(Account)]);
// Improved broker position matching with more robust logic
var brokerPosition = brokerPositions
var brokerPosition = liveBrokerPositions
.Where(p => p.Ticker == Config.Ticker)
.OrderByDescending(p => p.Open?.Date ?? DateTime.MinValue)
.FirstOrDefault(p => p.OriginDirection == positionForSignal.OriginDirection);
@@ -284,7 +281,7 @@ public class FuturesBot : TradingBotBase, ITradingBot
Logger.LogWarning(
$"⚠️ Position Sync Issue Detected\n" +
$"Internal position {internalPosition.Identifier} shows Filled\n" +
$"But not found in broker positions list (Count: {brokerPositions.Count})\n" +
$"But not found in broker positions list (Count: {liveBrokerPositions.Count})\n" +
$"Checking position history before marking as closed...");
// Verify in exchange history before assuming it's closed

View File

@@ -1,3 +1,4 @@
#nullable enable
using Managing.Application.Abstractions.Grains;
using Managing.Application.Abstractions.Services;
using Managing.Application.Trading.Commands;
@@ -68,15 +69,7 @@ public class SpotBot : TradingBotBase
// For live trading, get position from database via trading service
return await ServiceScopeHelpers.WithScopedService<ITradingService, Position>(
_scopeFactory,
async tradingService => { return await tradingService.GetPositionByIdentifierAsync(position.Identifier); });
}
protected override async Task<List<Position>> GetBrokerPositionsForUpdate(Account account)
{
// For live spot trading, we don't have broker positions like futures
// Positions are verified via token balances in UpdatePositionWithBrokerData and SynchronizeWithBrokerPositions
// Return empty list - actual verification happens in those methods
return new List<Position>();
async tradingService => await tradingService.GetPositionByIdentifierAsync(position.Identifier));
}
protected override async Task UpdatePositionWithBrokerData(Position position, List<Position> brokerPositions)
@@ -88,7 +81,7 @@ public class SpotBot : TradingBotBase
_scopeFactory,
async exchangeService => await exchangeService.GetBalance(Account, Config.Ticker));
if (tokenBalance == null || tokenBalance.Amount <= 0)
if (tokenBalance is not { Amount: > 0 })
{
// No token balance found - position might be closed
return;
@@ -225,8 +218,7 @@ public class SpotBot : TradingBotBase
}
protected override async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal,
List<Position> brokerPositions)
protected override async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal)
{
// For spot trading, fetch token balance directly and verify/match with internal position
try

View File

@@ -462,10 +462,9 @@ public abstract class TradingBotBase : ITradingBot
}
Position internalPosition = await GetInternalPositionForUpdate(positionForSignal);
var brokerPositions = await GetBrokerPositionsForUpdate(Account);
// Handle broker position synchronization (futures-specific logic)
await SynchronizeWithBrokerPositions(internalPosition, positionForSignal, brokerPositions);
await SynchronizeWithBrokerPositions(internalPosition, positionForSignal);
// Handle order management and position status (futures-specific logic)
await HandleOrderManagementAndPositionStatus(signal, internalPosition, positionForSignal);
@@ -650,8 +649,7 @@ public abstract class TradingBotBase : ITradingBot
}
// Virtual methods for trading mode-specific behavior
protected virtual async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal,
List<Position> brokerPositions)
protected virtual async Task SynchronizeWithBrokerPositions(Position internalPosition, Position positionForSignal)
{
// Default implementation: do nothing (for backtest)
}
@@ -1999,11 +1997,6 @@ public abstract class TradingBotBase : ITradingBot
return position; // Default implementation for backtest
}
protected virtual async Task<List<Position>> GetBrokerPositionsForUpdate(Account account)
{
return new List<Position>(); // Default implementation for backtest
}
protected virtual async Task UpdatePositionWithBrokerData(Position position, List<Position> brokerPositions)
{
// Default: do nothing for backtest