Refactor pagination sorting parameters across multiple controllers and services to use the new SortDirection enum; update related API models and TypeScript definitions for consistency. Fix minor documentation and naming inconsistencies in the Bot and Data controllers.
This commit is contained in:
@@ -206,7 +206,7 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
string? ticker = null,
|
||||
string? agentName = null,
|
||||
BotSortableColumn sortBy = BotSortableColumn.CreateDate,
|
||||
string sortDirection = "Desc",
|
||||
SortDirection sortDirection = SortDirection.Desc,
|
||||
bool showOnlyProfitable = false)
|
||||
{
|
||||
// Build the query with filters
|
||||
@@ -249,33 +249,33 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
// Apply sorting
|
||||
query = sortBy switch
|
||||
{
|
||||
BotSortableColumn.Name => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.Name => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.Name)
|
||||
: query.OrderByDescending(b => b.Name),
|
||||
BotSortableColumn.Ticker => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.Ticker => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.Ticker)
|
||||
: query.OrderByDescending(b => b.Ticker),
|
||||
BotSortableColumn.Status => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.Status => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.Status)
|
||||
: query.OrderByDescending(b => b.Status),
|
||||
BotSortableColumn.StartupTime => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.StartupTime => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.StartupTime)
|
||||
: query.OrderByDescending(b => b.StartupTime),
|
||||
BotSortableColumn.Roi => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.Roi => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.Roi)
|
||||
: query.OrderByDescending(b => b.Roi),
|
||||
BotSortableColumn.Pnl => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.Pnl => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.Pnl)
|
||||
: query.OrderByDescending(b => b.Pnl),
|
||||
BotSortableColumn.WinRate => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.WinRate => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b =>
|
||||
(b.TradeWins + b.TradeLosses) > 0 ? (double)b.TradeWins / (b.TradeWins + b.TradeLosses) : 0)
|
||||
: query.OrderByDescending(b =>
|
||||
(b.TradeWins + b.TradeLosses) > 0 ? (double)b.TradeWins / (b.TradeWins + b.TradeLosses) : 0),
|
||||
BotSortableColumn.AgentName => sortDirection.ToLower() == "asc"
|
||||
BotSortableColumn.AgentName => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.User.AgentName)
|
||||
: query.OrderByDescending(b => b.User.AgentName),
|
||||
_ => sortDirection.ToLower() == "asc"
|
||||
_ => sortDirection == SortDirection.Asc
|
||||
? query.OrderBy(b => b.CreateDate)
|
||||
: query.OrderByDescending(b => b.CreateDate)
|
||||
};
|
||||
|
||||
@@ -360,7 +360,9 @@ public static class PostgreSqlMappers
|
||||
Duration = backtest.EndDate - backtest.StartDate,
|
||||
MoneyManagementJson = JsonConvert.SerializeObject(backtest.Config?.MoneyManagement, jsonSettings),
|
||||
UserId = backtest.User?.Id ?? 0,
|
||||
StatisticsJson = backtest.Statistics != null ? JsonConvert.SerializeObject(backtest.Statistics, jsonSettings) : null,
|
||||
StatisticsJson = backtest.Statistics != null
|
||||
? JsonConvert.SerializeObject(backtest.Statistics, jsonSettings)
|
||||
: null,
|
||||
SharpeRatio = backtest.Statistics?.SharpeRatio ?? 0m,
|
||||
MaxDrawdown = backtest.Statistics?.MaxDrawdown ?? 0m,
|
||||
MaxDrawdownRecoveryTime = backtest.Statistics?.MaxDrawdownRecoveryTime ?? TimeSpan.Zero,
|
||||
@@ -503,7 +505,7 @@ public static class PostgreSqlMappers
|
||||
return new ScenarioEntity
|
||||
{
|
||||
Name = scenario.Name,
|
||||
LoopbackPeriod = scenario.LoopbackPeriod ?? 1,
|
||||
LoopbackPeriod = scenario.LookbackPeriod,
|
||||
UserId = scenario.User?.Id ?? 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace Managing.Infrastructure.Databases.PostgreSql;
|
||||
|
||||
public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRepository
|
||||
{
|
||||
public PostgreSqlTradingRepository(ManagingDbContext context, ILogger<SqlQueryLogger> logger, SentrySqlMonitoringService sentryMonitoringService)
|
||||
public PostgreSqlTradingRepository(ManagingDbContext context, ILogger<SqlQueryLogger> logger,
|
||||
SentrySqlMonitoringService sentryMonitoringService)
|
||||
: base(context, logger, sentryMonitoringService)
|
||||
{
|
||||
}
|
||||
@@ -154,7 +155,7 @@ public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRe
|
||||
|
||||
if (entity != null)
|
||||
{
|
||||
entity.LoopbackPeriod = scenario.LoopbackPeriod ?? 1;
|
||||
entity.LoopbackPeriod = scenario.LookbackPeriod;
|
||||
entity.UserId = scenario.User?.Id ?? 0;
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
@@ -408,62 +409,63 @@ public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRe
|
||||
public async Task UpdatePositionAsync(Position position)
|
||||
{
|
||||
await ExecuteWithLoggingAsync(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
|
||||
|
||||
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)
|
||||
try
|
||||
{
|
||||
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.MoneyManagementJson = position.MoneyManagement != null
|
||||
? JsonConvert.SerializeObject(position.MoneyManagement)
|
||||
: null;
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
await PostgreSqlConnectionHelper.EnsureConnectionOpenAsync(_context);
|
||||
|
||||
// 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)
|
||||
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)
|
||||
{
|
||||
UpdateTradeEntity(entity.OpenTrade, position.Open);
|
||||
}
|
||||
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.MoneyManagementJson = position.MoneyManagement != null
|
||||
? JsonConvert.SerializeObject(position.MoneyManagement)
|
||||
: null;
|
||||
entity.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
if (position.StopLoss != null && entity.StopLossTrade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.StopLossTrade, position.StopLoss);
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
UpdateTradeEntity(entity.OpenTrade, position.Open);
|
||||
}
|
||||
|
||||
if (position.TakeProfit1 != null && entity.TakeProfit1Trade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.TakeProfit1Trade, position.TakeProfit1);
|
||||
}
|
||||
if (position.StopLoss != null && entity.StopLossTrade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.StopLossTrade, position.StopLoss);
|
||||
}
|
||||
|
||||
if (position.TakeProfit2 != null && entity.TakeProfit2Trade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.TakeProfit2Trade, position.TakeProfit2);
|
||||
}
|
||||
if (position.TakeProfit1 != null && entity.TakeProfit1Trade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.TakeProfit1Trade, position.TakeProfit1);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
if (position.TakeProfit2 != null && entity.TakeProfit2Trade != null)
|
||||
{
|
||||
UpdateTradeEntity(entity.TakeProfit2Trade, position.TakeProfit2);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
|
||||
}
|
||||
}, nameof(UpdatePositionAsync), ("positionIdentifier", position.Identifier), ("positionStatus", position.Status));
|
||||
finally
|
||||
{
|
||||
await PostgreSqlConnectionHelper.SafeCloseConnectionAsync(_context);
|
||||
}
|
||||
}, nameof(UpdatePositionAsync), ("positionIdentifier", position.Identifier),
|
||||
("positionStatus", position.Status));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -474,7 +476,7 @@ public class PostgreSqlTradingRepository : BaseRepositoryWithLogging, ITradingRe
|
||||
{
|
||||
// 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 != trade.Status)
|
||||
if (entity.Status != trade.Status)
|
||||
{
|
||||
entity.Date = trade.Date;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user