Add filters and sorting for backtests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Text.Json;
|
||||
using Managing.Api.Models.Requests;
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Managing.Application.Abstractions.Shared;
|
||||
using Managing.Application.Hubs;
|
||||
using Managing.Domain.Backtests;
|
||||
using Managing.Domain.Bots;
|
||||
@@ -10,6 +11,7 @@ using Managing.Domain.Strategies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using static Managing.Common.Enums;
|
||||
using MoneyManagementRequest = Managing.Domain.Backtests.MoneyManagementRequest;
|
||||
|
||||
namespace Managing.Api.Controllers;
|
||||
@@ -231,8 +233,17 @@ public class BacktestController : BaseController
|
||||
public async Task<ActionResult<PaginatedBacktestsResponse>> GetBacktestsPaginated(
|
||||
int page = 1,
|
||||
int pageSize = 50,
|
||||
string sortBy = "score",
|
||||
string sortOrder = "desc")
|
||||
BacktestSortableColumn sortBy = BacktestSortableColumn.Score,
|
||||
string sortOrder = "desc",
|
||||
[FromQuery] double? scoreMin = null,
|
||||
[FromQuery] double? scoreMax = null,
|
||||
[FromQuery] int? winrateMin = null,
|
||||
[FromQuery] int? winrateMax = null,
|
||||
[FromQuery] decimal? maxDrawdownMax = null,
|
||||
[FromQuery] string? tickers = null,
|
||||
[FromQuery] string? indicators = null,
|
||||
[FromQuery] double? durationMinDays = null,
|
||||
[FromQuery] double? durationMaxDays = null)
|
||||
{
|
||||
var user = await GetUser();
|
||||
|
||||
@@ -251,8 +262,65 @@ public class BacktestController : BaseController
|
||||
return BadRequest("Sort order must be 'asc' or 'desc'");
|
||||
}
|
||||
|
||||
// Validate score and winrate ranges [0,100]
|
||||
if (scoreMin.HasValue && (scoreMin < 0 || scoreMin > 100))
|
||||
{
|
||||
return BadRequest("scoreMin must be between 0 and 100");
|
||||
}
|
||||
if (scoreMax.HasValue && (scoreMax < 0 || scoreMax > 100))
|
||||
{
|
||||
return BadRequest("scoreMax must be between 0 and 100");
|
||||
}
|
||||
if (winrateMin.HasValue && (winrateMin < 0 || winrateMin > 100))
|
||||
{
|
||||
return BadRequest("winrateMin must be between 0 and 100");
|
||||
}
|
||||
if (winrateMax.HasValue && (winrateMax < 0 || winrateMax > 100))
|
||||
{
|
||||
return BadRequest("winrateMax must be between 0 and 100");
|
||||
}
|
||||
|
||||
if (scoreMin.HasValue && scoreMax.HasValue && scoreMin > scoreMax)
|
||||
{
|
||||
return BadRequest("scoreMin must be less than or equal to scoreMax");
|
||||
}
|
||||
if (winrateMin.HasValue && winrateMax.HasValue && winrateMin > winrateMax)
|
||||
{
|
||||
return BadRequest("winrateMin must be less than or equal to winrateMax");
|
||||
}
|
||||
if (maxDrawdownMax.HasValue && maxDrawdownMax < 0)
|
||||
{
|
||||
return BadRequest("maxDrawdownMax must be greater than or equal to 0");
|
||||
}
|
||||
|
||||
// Parse multi-selects if provided (comma-separated). Currently unused until repository wiring.
|
||||
var tickerList = string.IsNullOrWhiteSpace(tickers)
|
||||
? Array.Empty<string>()
|
||||
: tickers.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
var indicatorList = string.IsNullOrWhiteSpace(indicators)
|
||||
? Array.Empty<string>()
|
||||
: indicators.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
var filter = new BacktestsFilter
|
||||
{
|
||||
ScoreMin = scoreMin,
|
||||
ScoreMax = scoreMax,
|
||||
WinrateMin = winrateMin,
|
||||
WinrateMax = winrateMax,
|
||||
MaxDrawdownMax = maxDrawdownMax,
|
||||
Tickers = tickerList,
|
||||
Indicators = indicatorList,
|
||||
DurationMin = durationMinDays.HasValue ? TimeSpan.FromDays(durationMinDays.Value) : (TimeSpan?)null,
|
||||
DurationMax = durationMaxDays.HasValue ? TimeSpan.FromDays(durationMaxDays.Value) : (TimeSpan?)null
|
||||
};
|
||||
|
||||
var (backtests, totalCount) =
|
||||
await _backtester.GetBacktestsByUserPaginatedAsync(user, page, pageSize, sortBy, sortOrder);
|
||||
await _backtester.GetBacktestsByUserPaginatedAsync(
|
||||
user,
|
||||
page,
|
||||
pageSize,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
filter);
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
|
||||
var response = new PaginatedBacktestsResponse
|
||||
|
||||
Reference in New Issue
Block a user