Add cache for position

This commit is contained in:
2025-10-10 02:48:50 +07:00
parent 5a91c0fdd1
commit 3128e3e9d9
2 changed files with 40 additions and 9 deletions

View File

@@ -480,8 +480,23 @@ public class DataController : ControllerBase
decimal totalVolume = strategy.Volume;
decimal volumeLast24h = strategy.Volume;
// Fetch positions associated with this bot using the provided trading service
var positions = await tradingService.GetPositionsByInitiatorIdentifierAsync(strategy.Identifier);
// Use caching for position data in UI context (not critical trading operations)
var cacheKey = $"positions_{strategy.Identifier}";
var cachedPositions = _cacheService.GetValue<List<Position>>(cacheKey);
List<Position> positions;
if (cachedPositions != null)
{
positions = cachedPositions;
}
else
{
// Fetch positions associated with this bot using the provided trading service
positions = (await tradingService.GetPositionsByInitiatorIdentifierAsync(strategy.Identifier)).ToList();
// Cache positions for 2 minutes for UI display purposes
_cacheService.SaveValue(cacheKey, positions, TimeSpan.FromMinutes(2));
}
// Calculate win/loss statistics from actual positions (including open positions)
int wins = positions.Count(p => p.ProfitAndLoss != null && p.ProfitAndLoss.Realized > 0);

View File

@@ -273,17 +273,33 @@ public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRe
{
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
// Optimized query with explicit JOINs to avoid N+1 queries
var position = await _context.Positions
.AsNoTracking()
.Include(p => p.User)
.Include(p => p.OpenTrade)
.Include(p => p.StopLossTrade)
.Include(p => p.TakeProfit1Trade)
.Include(p => p.TakeProfit2Trade)
.FirstOrDefaultAsync(p => p.Identifier == identifier)
.Where(p => p.Identifier == identifier)
.Select(p => new
{
Position = p,
User = p.User,
OpenTrade = p.OpenTrade,
StopLossTrade = p.StopLossTrade,
TakeProfit1Trade = p.TakeProfit1Trade,
TakeProfit2Trade = p.TakeProfit2Trade
})
.FirstOrDefaultAsync()
.ConfigureAwait(false);
return PostgreSqlMappers.Map(position ?? throw new InvalidOperationException("Position not found"));
if (position == null)
throw new InvalidOperationException("Position not found");
// Manually assign navigation properties to avoid lazy loading
position.Position.User = position.User;
position.Position.OpenTrade = position.OpenTrade;
position.Position.StopLossTrade = position.StopLossTrade;
position.Position.TakeProfit1Trade = position.TakeProfit1Trade;
position.Position.TakeProfit2Trade = position.TakeProfit2Trade;
return PostgreSqlMappers.Map(position.Position);
}
finally
{