Refactor BotController and BotService for improved bot management

- Cleaned up constructor parameters in BotController for better readability.
- Enhanced StartCopyTradingCommand handling with improved formatting.
- Updated bot deletion logic in BotService to delete associated positions and trigger agent summary updates.
- Added new method in TradingService for deleting positions by initiator identifier.
- Implemented error handling in StopBotCommandHandler to ensure agent summary updates do not disrupt bot stop operations.
This commit is contained in:
2025-11-23 15:30:11 +07:00
parent 9c8ab71736
commit 411fc41bef
8 changed files with 558 additions and 13 deletions

View File

@@ -529,6 +529,84 @@ public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRe
return PostgreSqlMappers.Map(positions);
}
public async Task DeletePositionsByInitiatorIdentifierAsync(Guid initiatorIdentifier)
{
await ExecuteWithLoggingAsync(async () =>
{
try
{
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
// First, collect all trade IDs that need to be deleted using separate queries for each trade type
var openTradeIds = await _context.Positions
.AsNoTracking()
.Where(p => p.InitiatorIdentifier == initiatorIdentifier && p.OpenTradeId.HasValue)
.Select(p => p.OpenTradeId.Value)
.ToListAsync()
.ConfigureAwait(false);
var stopLossTradeIds = await _context.Positions
.AsNoTracking()
.Where(p => p.InitiatorIdentifier == initiatorIdentifier && p.StopLossTradeId.HasValue)
.Select(p => p.StopLossTradeId.Value)
.ToListAsync()
.ConfigureAwait(false);
var takeProfit1TradeIds = await _context.Positions
.AsNoTracking()
.Where(p => p.InitiatorIdentifier == initiatorIdentifier && p.TakeProfit1TradeId.HasValue)
.Select(p => p.TakeProfit1TradeId.Value)
.ToListAsync()
.ConfigureAwait(false);
var takeProfit2TradeIds = await _context.Positions
.AsNoTracking()
.Where(p => p.InitiatorIdentifier == initiatorIdentifier && p.TakeProfit2TradeId.HasValue)
.Select(p => p.TakeProfit2TradeId.Value)
.ToListAsync()
.ConfigureAwait(false);
// Combine all trade IDs and remove duplicates
var tradeIdsToDelete = openTradeIds
.Concat(stopLossTradeIds)
.Concat(takeProfit1TradeIds)
.Concat(takeProfit2TradeIds)
.Distinct()
.ToList();
// Delete trades first (due to foreign key constraints)
if (tradeIdsToDelete.Any())
{
var tradesToDelete = await _context.Trades
.AsTracking()
.Where(t => tradeIdsToDelete.Contains(t.Id))
.ToListAsync()
.ConfigureAwait(false);
_context.Trades.RemoveRange(tradesToDelete);
}
// Then delete all positions with the given initiator identifier
var positionsToDelete = await _context.Positions
.AsTracking()
.Where(p => p.InitiatorIdentifier == initiatorIdentifier)
.ToListAsync()
.ConfigureAwait(false);
if (positionsToDelete.Any())
{
_context.Positions.RemoveRange(positionsToDelete);
}
await _context.SaveChangesAsync();
}
finally
{
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
}
}, nameof(DeletePositionsByInitiatorIdentifierAsync), ("initiatorIdentifier", initiatorIdentifier));
}
public async Task<IEnumerable<Position>> GetAllPositionsAsync()
{
var positions = await _context.Positions