diff --git a/src/Managing.Application.Abstractions/Repositories/ITradingRepository.cs b/src/Managing.Application.Abstractions/Repositories/ITradingRepository.cs index 3ab88bb1..27d3d069 100644 --- a/src/Managing.Application.Abstractions/Repositories/ITradingRepository.cs +++ b/src/Managing.Application.Abstractions/Repositories/ITradingRepository.cs @@ -34,6 +34,5 @@ public interface ITradingRepository Task UpdateStrategyAsync(IndicatorBase indicatorBase); Task GetStrategyByNameUserAsync(string name, User user); Task GetScenarioByNameUserAsync(string scenarioName, User user); - Task UpdateTradeAsync(Trade trade); Task> GetPositionByUserIdAsync(int userId); } \ No newline at end of file diff --git a/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlTradingRepository.cs b/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlTradingRepository.cs index 9262a948..fd330323 100644 --- a/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlTradingRepository.cs +++ b/src/Managing.Infrastructure.Database/PostgreSql/PostgreSqlTradingRepository.cs @@ -391,70 +391,71 @@ public class PostgreSqlTradingRepository : ITradingRepository { var entity = _context.Positions .AsTracking() + .Include(p => p.OpenTrade) + .Include(p => p.StopLossTrade) + .Include(p => p.TakeProfit1Trade) + .Include(p => p.TakeProfit2Trade) .FirstOrDefault(p => p.Identifier == position.Identifier); if (entity != null) { - entity.Date = position.Date; entity.ProfitAndLoss = position.ProfitAndLoss?.Realized ?? 0; entity.NetPnL = position.ProfitAndLoss?.Net ?? 0; entity.UiFees = position.UiFees; entity.OriginDirection = position.OriginDirection; entity.GasFees = position.GasFees; entity.Status = position.Status; - entity.SignalIdentifier = position.SignalIdentifier; entity.MoneyManagementJson = position.MoneyManagement != null ? JsonConvert.SerializeObject(position.MoneyManagement) : null; entity.UpdatedAt = DateTime.UtcNow; - // Update related trades - if (position.Open != null) + // Update related trades directly through the position's trade references + // This ensures we're updating the correct trade records for this specific position + if (position.Open != null && entity.OpenTrade != null) { - await UpdateTradeAsync(position.Open); + UpdateTradeEntity(entity.OpenTrade, position.Open); } - if (position.StopLoss != null) + if (position.StopLoss != null && entity.StopLossTrade != null) { - await UpdateTradeAsync(position.StopLoss); + UpdateTradeEntity(entity.StopLossTrade, position.StopLoss); } - if (position.TakeProfit1 != null) + if (position.TakeProfit1 != null && entity.TakeProfit1Trade != null) { - await UpdateTradeAsync(position.TakeProfit1); + UpdateTradeEntity(entity.TakeProfit1Trade, position.TakeProfit1); } - if (position.TakeProfit2 != null) + if (position.TakeProfit2 != null && entity.TakeProfit2Trade != null) { - await UpdateTradeAsync(position.TakeProfit2); + UpdateTradeEntity(entity.TakeProfit2Trade, position.TakeProfit2); } await _context.SaveChangesAsync(); } } - public async Task UpdateTradeAsync(Trade trade) + /// + /// Updates a trade entity with data from a domain trade object + /// Only updates the date if the trade status is changing from Requested to Filled + /// + private void UpdateTradeEntity(TradeEntity entity, Trade trade) { - var entity = _context.Trades - .AsTracking() - .FirstOrDefault(t => t.ExchangeOrderId == trade.ExchangeOrderId); - - if (entity != null) + // Only update the date if the trade status is changing from Requested to Filled + // This prevents overwriting dates for trades that are already filled + if (entity.Status != TradeStatus.Filled && trade.Status == TradeStatus.Filled) { entity.Date = trade.Date; - entity.Direction = trade.Direction; - entity.Status = trade.Status; - entity.TradeType = trade.TradeType; - entity.Ticker = trade.Ticker; - entity.Quantity = trade.Quantity; - entity.Price = trade.Price; - entity.Leverage = trade.Leverage; - entity.ExchangeOrderId = trade.ExchangeOrderId; - entity.Message = trade.Message; - entity.UpdatedAt = DateTime.UtcNow; - - await _context.SaveChangesAsync(); } + + entity.Status = trade.Status; + entity.Quantity = trade.Quantity; + entity.Price = trade.Price; + entity.Leverage = trade.Leverage; + entity.ExchangeOrderId = trade.ExchangeOrderId; + entity.Message = trade.Message; + entity.UpdatedAt = DateTime.UtcNow; } public async Task> GetPositionsByInitiatorIdentifierAsync(Guid initiatorIdentifier) @@ -627,6 +628,7 @@ public class PostgreSqlTradingRepository : ITradingRepository .Include(p => p.TakeProfit1Trade) .Include(p => p.TakeProfit2Trade) .Where(p => p.UserId == userId) + .OrderBy(p => p.Date) .ToListAsync() .ConfigureAwait(false); return PostgreSqlMappers.Map(positions);