Fix bot TOP 3
This commit is contained in:
@@ -329,31 +329,24 @@ public class DataController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the top 3 performing strategies based on ROI.
|
/// Retrieves the top 3 performing strategies based on PnL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="TopStrategiesViewModel"/> containing the top performing strategies.</returns>
|
/// <returns>A <see cref="TopStrategiesViewModel"/> containing the top performing strategies.</returns>
|
||||||
[HttpGet("GetTopStrategies")]
|
[HttpGet("GetTopStrategies")]
|
||||||
public async Task<ActionResult<TopStrategiesViewModel>> GetTopStrategies()
|
public async Task<ActionResult<TopStrategiesViewModel>> GetTopStrategies()
|
||||||
{
|
{
|
||||||
// Get active bots
|
// Get top 3 bots by PnL directly from database (both running and stopped)
|
||||||
var activeBots = await _mediator.Send(new GetBotsByStatusCommand(BotStatus.Running));
|
var bots = await _mediator.Send(new GetTopBotsByPnLCommand(new[] { BotStatus.Running, BotStatus.Stopped }, 3));
|
||||||
|
|
||||||
// Calculate PnL for each bot once and store in a list of tuples
|
|
||||||
var botsWithPnL = activeBots
|
|
||||||
.Select(bot => new { Bot = bot, PnL = bot.Pnl, agentName = bot.User.AgentName })
|
|
||||||
.OrderByDescending(item => item.PnL)
|
|
||||||
.Take(3)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// Map to view model
|
// Map to view model
|
||||||
var topStrategies = new TopStrategiesViewModel
|
var topStrategies = new TopStrategiesViewModel
|
||||||
{
|
{
|
||||||
TopStrategies = botsWithPnL
|
TopStrategies = bots
|
||||||
.Select(item => new StrategyPerformance
|
.Select(bot => new StrategyPerformance
|
||||||
{
|
{
|
||||||
StrategyName = item.Bot.Name,
|
StrategyName = bot.Name,
|
||||||
PnL = item.PnL,
|
PnL = bot.Pnl,
|
||||||
AgentName = item.agentName,
|
AgentName = bot.User.AgentName,
|
||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
};
|
};
|
||||||
@@ -368,26 +361,19 @@ public class DataController : ControllerBase
|
|||||||
[HttpGet("GetTopStrategiesByRoi")]
|
[HttpGet("GetTopStrategiesByRoi")]
|
||||||
public async Task<ActionResult<TopStrategiesByRoiViewModel>> GetTopStrategiesByRoi()
|
public async Task<ActionResult<TopStrategiesByRoiViewModel>> GetTopStrategiesByRoi()
|
||||||
{
|
{
|
||||||
// Get active bots
|
// Get top 3 bots by ROI directly from database (both running and stopped)
|
||||||
var activeBots = await _mediator.Send(new GetBotsByStatusCommand(BotStatus.Running));
|
var bots = await _mediator.Send(new GetTopBotsByRoiCommand(new[] { BotStatus.Running, BotStatus.Stopped }, 3));
|
||||||
|
|
||||||
// Filter bots with valid ROI data and order by ROI
|
|
||||||
var botsWithRoi = activeBots
|
|
||||||
.Select(bot => new { Bot = bot, Roi = bot.Roi, PnL = bot.Pnl, Volume = bot.Volume })
|
|
||||||
.OrderByDescending(item => item.Roi)
|
|
||||||
.Take(3)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// Map to view model
|
// Map to view model
|
||||||
var topStrategiesByRoi = new TopStrategiesByRoiViewModel
|
var topStrategiesByRoi = new TopStrategiesByRoiViewModel
|
||||||
{
|
{
|
||||||
TopStrategiesByRoi = botsWithRoi
|
TopStrategiesByRoi = bots
|
||||||
.Select(item => new StrategyRoiPerformance
|
.Select(bot => new StrategyRoiPerformance
|
||||||
{
|
{
|
||||||
StrategyName = item.Bot.Name,
|
StrategyName = bot.Name,
|
||||||
Roi = item.Roi,
|
Roi = bot.Roi,
|
||||||
PnL = item.PnL,
|
PnL = bot.Pnl,
|
||||||
Volume = item.Volume
|
Volume = bot.Volume
|
||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,4 +37,20 @@ public interface IBotRepository
|
|||||||
string? agentName = null,
|
string? agentName = null,
|
||||||
string sortBy = "CreateDate",
|
string sortBy = "CreateDate",
|
||||||
string sortDirection = "Desc");
|
string sortDirection = "Desc");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the top performing bots by PnL from the specified statuses
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="statuses">Bot statuses to include in the query</param>
|
||||||
|
/// <param name="count">Number of top performers to return (default: 3)</param>
|
||||||
|
/// <returns>Top performing bots ordered by PnL descending</returns>
|
||||||
|
Task<IEnumerable<Bot>> GetTopBotsByPnLAsync(IEnumerable<BotStatus> statuses, int count = 3);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the top performing bots by ROI from the specified statuses
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="statuses">Bot statuses to include in the query</param>
|
||||||
|
/// <param name="count">Number of top performers to return (default: 3)</param>
|
||||||
|
/// <returns>Top performing bots ordered by ROI descending</returns>
|
||||||
|
Task<IEnumerable<Bot>> GetTopBotsByRoiAsync(IEnumerable<BotStatus> statuses, int count = 3);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Managing.Domain.Bots;
|
||||||
|
using MediatR;
|
||||||
|
using static Managing.Common.Enums;
|
||||||
|
|
||||||
|
namespace Managing.Application.ManageBot.Commands
|
||||||
|
{
|
||||||
|
public class GetTopBotsByPnLCommand : IRequest<IEnumerable<Bot>>
|
||||||
|
{
|
||||||
|
public IEnumerable<BotStatus> Statuses { get; }
|
||||||
|
public int Count { get; }
|
||||||
|
|
||||||
|
public GetTopBotsByPnLCommand(IEnumerable<BotStatus> statuses, int count = 3)
|
||||||
|
{
|
||||||
|
Statuses = statuses;
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Managing.Domain.Bots;
|
||||||
|
using MediatR;
|
||||||
|
using static Managing.Common.Enums;
|
||||||
|
|
||||||
|
namespace Managing.Application.ManageBot.Commands
|
||||||
|
{
|
||||||
|
public class GetTopBotsByRoiCommand : IRequest<IEnumerable<Bot>>
|
||||||
|
{
|
||||||
|
public IEnumerable<BotStatus> Statuses { get; }
|
||||||
|
public int Count { get; }
|
||||||
|
|
||||||
|
public GetTopBotsByRoiCommand(IEnumerable<BotStatus> statuses, int count = 3)
|
||||||
|
{
|
||||||
|
Statuses = statuses;
|
||||||
|
Count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Managing.Application.Abstractions.Repositories;
|
||||||
|
using Managing.Application.ManageBot.Commands;
|
||||||
|
using Managing.Domain.Bots;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace Managing.Application.ManageBot
|
||||||
|
{
|
||||||
|
public class GetTopBotsByPnLCommandHandler(IBotRepository botRepository)
|
||||||
|
: IRequestHandler<GetTopBotsByPnLCommand, IEnumerable<Bot>>
|
||||||
|
{
|
||||||
|
public async Task<IEnumerable<Bot>> Handle(GetTopBotsByPnLCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await botRepository.GetTopBotsByPnLAsync(request.Statuses, request.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Managing.Application.Abstractions.Repositories;
|
||||||
|
using Managing.Application.ManageBot.Commands;
|
||||||
|
using Managing.Domain.Bots;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace Managing.Application.ManageBot
|
||||||
|
{
|
||||||
|
public class GetTopBotsByRoiCommandHandler(IBotRepository botRepository)
|
||||||
|
: IRequestHandler<GetTopBotsByRoiCommand, IEnumerable<Bot>>
|
||||||
|
{
|
||||||
|
public async Task<IEnumerable<Bot>> Handle(GetTopBotsByRoiCommand request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await botRepository.GetTopBotsByRoiAsync(request.Statuses, request.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -239,4 +239,32 @@ public class PostgreSqlBotRepository : IBotRepository
|
|||||||
var bots = PostgreSqlMappers.Map(entities);
|
var bots = PostgreSqlMappers.Map(entities);
|
||||||
return (bots, totalCount);
|
return (bots, totalCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Bot>> GetTopBotsByPnLAsync(IEnumerable<BotStatus> statuses, int count = 3)
|
||||||
|
{
|
||||||
|
var entities = await _context.Bots
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(m => m.User)
|
||||||
|
.Where(b => statuses.Contains(b.Status))
|
||||||
|
.OrderByDescending(b => b.Pnl)
|
||||||
|
.Take(count)
|
||||||
|
.ToListAsync()
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return PostgreSqlMappers.Map(entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<Bot>> GetTopBotsByRoiAsync(IEnumerable<BotStatus> statuses, int count = 3)
|
||||||
|
{
|
||||||
|
var entities = await _context.Bots
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(m => m.User)
|
||||||
|
.Where(b => statuses.Contains(b.Status))
|
||||||
|
.OrderByDescending(b => b.Roi)
|
||||||
|
.Take(count)
|
||||||
|
.ToListAsync()
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return PostgreSqlMappers.Map(entities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user