Add agent index with pagination
This commit is contained in:
@@ -664,6 +664,198 @@ public class DataController : ControllerBase
|
||||
return Ok(agentIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of agent summaries for the agent index page
|
||||
/// </summary>
|
||||
/// <param name="timeFilter">Time filter to apply (24H, 3D, 1W, 1M, 1Y, Total)</param>
|
||||
/// <param name="page">Page number (defaults to 1)</param>
|
||||
/// <param name="pageSize">Number of items per page (defaults to 10, max 100)</param>
|
||||
/// <param name="sortBy">Field to sort by (TotalPnL, PnLLast24h, TotalROI, ROILast24h, Wins, Losses, AverageWinRate, ActiveStrategiesCount, TotalVolume, VolumeLast24h)</param>
|
||||
/// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
|
||||
/// <returns>A paginated list of agent summaries sorted by the specified field</returns>
|
||||
[HttpGet("GetAgentIndexPaginated")]
|
||||
public async Task<ActionResult<PaginatedAgentIndexResponse>> GetAgentIndexPaginated(
|
||||
string timeFilter = "Total",
|
||||
int page = 1,
|
||||
int pageSize = 10,
|
||||
string sortBy = "TotalPnL",
|
||||
string sortOrder = "desc")
|
||||
{
|
||||
// Validate time filter
|
||||
var validTimeFilters = new[] { "24H", "3D", "1W", "1M", "1Y", "Total" };
|
||||
if (!validTimeFilters.Contains(timeFilter))
|
||||
{
|
||||
timeFilter = "Total"; // Default to Total if invalid
|
||||
}
|
||||
|
||||
// Validate pagination parameters
|
||||
if (page < 1)
|
||||
{
|
||||
return BadRequest("Page must be greater than 0");
|
||||
}
|
||||
|
||||
if (pageSize < 1 || pageSize > 100)
|
||||
{
|
||||
return BadRequest("Page size must be between 1 and 100");
|
||||
}
|
||||
|
||||
// Validate sort order
|
||||
if (sortOrder != "asc" && sortOrder != "desc")
|
||||
{
|
||||
return BadRequest("Sort order must be 'asc' or 'desc'");
|
||||
}
|
||||
|
||||
// Validate sort by field
|
||||
var validSortFields = new[] { "TotalPnL", "PnLLast24h", "TotalROI", "ROILast24h", "Wins", "Losses", "AverageWinRate", "ActiveStrategiesCount", "TotalVolume", "VolumeLast24h" };
|
||||
if (!validSortFields.Contains(sortBy))
|
||||
{
|
||||
sortBy = "TotalPnL"; // Default to TotalPnL if invalid
|
||||
}
|
||||
|
||||
string cacheKey = $"AgentIndex_{timeFilter}";
|
||||
|
||||
// Check if the agent index is already cached
|
||||
var cachedIndex = _cacheService.GetValue<AgentIndexViewModel>(cacheKey);
|
||||
|
||||
List<AgentSummaryViewModel> allAgentSummaries;
|
||||
|
||||
if (cachedIndex != null)
|
||||
{
|
||||
allAgentSummaries = cachedIndex.AgentSummaries.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get all agents and their strategies
|
||||
var agentsWithStrategies = await _mediator.Send(new GetAllAgentsCommand(timeFilter));
|
||||
|
||||
allAgentSummaries = new List<AgentSummaryViewModel>();
|
||||
|
||||
// Create summaries for each agent
|
||||
foreach (var agent in agentsWithStrategies)
|
||||
{
|
||||
var user = agent.Key;
|
||||
var strategies = agent.Value;
|
||||
|
||||
if (strategies.Count == 0)
|
||||
{
|
||||
continue; // Skip agents with no strategies
|
||||
}
|
||||
|
||||
// Combine all positions from all strategies
|
||||
var allPositions = strategies.SelectMany<ITradingBot, Position>(s => s.Positions).ToList();
|
||||
|
||||
// Calculate agent metrics
|
||||
decimal totalPnL = TradingBox.GetPnLInTimeRange(allPositions, timeFilter);
|
||||
decimal pnlLast24h = TradingBox.GetPnLInTimeRange(allPositions, "24H");
|
||||
|
||||
decimal totalROI = TradingBox.GetROIInTimeRange(allPositions, timeFilter);
|
||||
decimal roiLast24h = TradingBox.GetROIInTimeRange(allPositions, "24H");
|
||||
|
||||
(int wins, int losses) = TradingBox.GetWinLossCountInTimeRange(allPositions, timeFilter);
|
||||
|
||||
// Calculate trading volumes
|
||||
decimal totalVolume = TradingBox.GetTotalVolumeTraded(allPositions);
|
||||
decimal volumeLast24h = TradingBox.GetLast24HVolumeTraded(allPositions);
|
||||
|
||||
// Calculate win rate
|
||||
int averageWinRate = 0;
|
||||
if (wins + losses > 0)
|
||||
{
|
||||
averageWinRate = (wins * 100) / (wins + losses);
|
||||
}
|
||||
|
||||
// Add to agent summaries
|
||||
var agentSummary = new AgentSummaryViewModel
|
||||
{
|
||||
AgentName = user.AgentName,
|
||||
TotalPnL = totalPnL,
|
||||
PnLLast24h = pnlLast24h,
|
||||
TotalROI = totalROI,
|
||||
ROILast24h = roiLast24h,
|
||||
Wins = wins,
|
||||
Losses = losses,
|
||||
AverageWinRate = averageWinRate,
|
||||
ActiveStrategiesCount = strategies.Count,
|
||||
TotalVolume = totalVolume,
|
||||
VolumeLast24h = volumeLast24h
|
||||
};
|
||||
|
||||
allAgentSummaries.Add(agentSummary);
|
||||
}
|
||||
|
||||
// Cache the results for 5 minutes
|
||||
var agentIndex = new AgentIndexViewModel
|
||||
{
|
||||
TimeFilter = timeFilter,
|
||||
AgentSummaries = allAgentSummaries
|
||||
};
|
||||
_cacheService.SaveValue(cacheKey, agentIndex, TimeSpan.FromMinutes(5));
|
||||
}
|
||||
|
||||
// Apply sorting
|
||||
var sortedSummaries = sortBy switch
|
||||
{
|
||||
"TotalPnL" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.TotalPnL)
|
||||
: allAgentSummaries.OrderBy(a => a.TotalPnL),
|
||||
"PnLLast24h" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.PnLLast24h)
|
||||
: allAgentSummaries.OrderBy(a => a.PnLLast24h),
|
||||
"TotalROI" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.TotalROI)
|
||||
: allAgentSummaries.OrderBy(a => a.TotalROI),
|
||||
"ROILast24h" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.ROILast24h)
|
||||
: allAgentSummaries.OrderBy(a => a.ROILast24h),
|
||||
"Wins" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.Wins)
|
||||
: allAgentSummaries.OrderBy(a => a.Wins),
|
||||
"Losses" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.Losses)
|
||||
: allAgentSummaries.OrderBy(a => a.Losses),
|
||||
"AverageWinRate" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.AverageWinRate)
|
||||
: allAgentSummaries.OrderBy(a => a.AverageWinRate),
|
||||
"ActiveStrategiesCount" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.ActiveStrategiesCount)
|
||||
: allAgentSummaries.OrderBy(a => a.ActiveStrategiesCount),
|
||||
"TotalVolume" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.TotalVolume)
|
||||
: allAgentSummaries.OrderBy(a => a.TotalVolume),
|
||||
"VolumeLast24h" => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.VolumeLast24h)
|
||||
: allAgentSummaries.OrderBy(a => a.VolumeLast24h),
|
||||
_ => sortOrder == "desc"
|
||||
? allAgentSummaries.OrderByDescending(a => a.TotalPnL)
|
||||
: allAgentSummaries.OrderBy(a => a.TotalPnL)
|
||||
};
|
||||
|
||||
var totalCount = allAgentSummaries.Count;
|
||||
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
|
||||
|
||||
// Apply pagination
|
||||
var paginatedSummaries = sortedSummaries
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
var response = new PaginatedAgentIndexResponse
|
||||
{
|
||||
AgentSummaries = paginatedSummaries,
|
||||
TotalCount = totalCount,
|
||||
CurrentPage = page,
|
||||
PageSize = pageSize,
|
||||
TotalPages = totalPages,
|
||||
HasNextPage = page < totalPages,
|
||||
HasPreviousPage = page > 1,
|
||||
TimeFilter = timeFilter,
|
||||
SortBy = sortBy,
|
||||
SortOrder = sortOrder
|
||||
};
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves balance history for a specific agent within a date range
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user