Add best agent by pnl
This commit is contained in:
@@ -400,6 +400,49 @@ public class DataController : ControllerBase
|
|||||||
return Ok(topStrategiesByRoi);
|
return Ok(topStrategiesByRoi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the top 3 performing agents based on PnL.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="TopAgentsByPnLViewModel"/> containing the top performing agents by PnL.</returns>
|
||||||
|
[HttpGet("GetTopAgentsByPnL")]
|
||||||
|
public async Task<ActionResult<TopAgentsByPnLViewModel>> GetTopAgentsByPnL()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get all agent summaries
|
||||||
|
var allAgentSummaries = await _mediator.Send(new GetAllAgentSummariesCommand("Total"));
|
||||||
|
|
||||||
|
// Filter agents with valid PnL data and order by PnL
|
||||||
|
var agentsWithPnL = allAgentSummaries
|
||||||
|
.Where(agent => agent.TotalPnL != 0) // Only include agents with actual PnL
|
||||||
|
.OrderByDescending(agent => agent.TotalPnL)
|
||||||
|
.Take(3)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// Map to view model
|
||||||
|
var topAgentsByPnL = new TopAgentsByPnLViewModel
|
||||||
|
{
|
||||||
|
TopAgentsByPnL = agentsWithPnL
|
||||||
|
.Select(agent => new AgentPerformance
|
||||||
|
{
|
||||||
|
AgentName = agent.AgentName,
|
||||||
|
PnL = agent.TotalPnL,
|
||||||
|
TotalROI = agent.TotalROI,
|
||||||
|
TotalVolume = agent.TotalVolume,
|
||||||
|
ActiveStrategiesCount = agent.ActiveStrategiesCount,
|
||||||
|
TotalBalance = agent.TotalBalance
|
||||||
|
})
|
||||||
|
.ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(topAgentsByPnL);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"Error retrieving top agents by PnL: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves list of the active strategies for a user with detailed information
|
/// Retrieves list of the active strategies for a user with detailed information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -65,4 +65,51 @@ namespace Managing.Api.Models.Responses
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<StrategyRoiPerformance> TopStrategiesByRoi { get; set; } = new List<StrategyRoiPerformance>();
|
public List<StrategyRoiPerformance> TopStrategiesByRoi { get; set; } = new List<StrategyRoiPerformance>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a high-performing agent with its name and PnL value
|
||||||
|
/// </summary>
|
||||||
|
public class AgentPerformance
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the agent
|
||||||
|
/// </summary>
|
||||||
|
public string AgentName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Profit and Loss value of the agent
|
||||||
|
/// </summary>
|
||||||
|
public decimal PnL { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total ROI percentage of the agent
|
||||||
|
/// </summary>
|
||||||
|
public decimal TotalROI { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total volume traded by the agent
|
||||||
|
/// </summary>
|
||||||
|
public decimal TotalVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of active strategies for this agent
|
||||||
|
/// </summary>
|
||||||
|
public int ActiveStrategiesCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total balance including USDC and open position values
|
||||||
|
/// </summary>
|
||||||
|
public decimal TotalBalance { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// View model containing the top performing agents by PnL
|
||||||
|
/// </summary>
|
||||||
|
public class TopAgentsByPnLViewModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of the top performing agents by PnL
|
||||||
|
/// </summary>
|
||||||
|
public List<AgentPerformance> TopAgentsByPnL { get; set; } = new List<AgentPerformance>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1939,6 +1939,41 @@ export class DataClient extends AuthorizedApiBase {
|
|||||||
return Promise.resolve<TopStrategiesByRoiViewModel>(null as any);
|
return Promise.resolve<TopStrategiesByRoiViewModel>(null as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data_GetTopAgentsByPnL(): Promise<TopAgentsByPnLViewModel> {
|
||||||
|
let url_ = this.baseUrl + "/Data/GetTopAgentsByPnL";
|
||||||
|
url_ = url_.replace(/[?&]$/, "");
|
||||||
|
|
||||||
|
let options_: RequestInit = {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Accept": "application/json"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.transformOptions(options_).then(transformedOptions_ => {
|
||||||
|
return this.http.fetch(url_, transformedOptions_);
|
||||||
|
}).then((_response: Response) => {
|
||||||
|
return this.processData_GetTopAgentsByPnL(_response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected processData_GetTopAgentsByPnL(response: Response): Promise<TopAgentsByPnLViewModel> {
|
||||||
|
const status = response.status;
|
||||||
|
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
||||||
|
if (status === 200) {
|
||||||
|
return response.text().then((_responseText) => {
|
||||||
|
let result200: any = null;
|
||||||
|
result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as TopAgentsByPnLViewModel;
|
||||||
|
return result200;
|
||||||
|
});
|
||||||
|
} else if (status !== 200 && status !== 204) {
|
||||||
|
return response.text().then((_responseText) => {
|
||||||
|
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve<TopAgentsByPnLViewModel>(null as any);
|
||||||
|
}
|
||||||
|
|
||||||
data_GetUserStrategies(agentName: string | null | undefined): Promise<UserStrategyDetailsViewModel[]> {
|
data_GetUserStrategies(agentName: string | null | undefined): Promise<UserStrategyDetailsViewModel[]> {
|
||||||
let url_ = this.baseUrl + "/Data/GetUserStrategies?";
|
let url_ = this.baseUrl + "/Data/GetUserStrategies?";
|
||||||
if (agentName !== undefined && agentName !== null)
|
if (agentName !== undefined && agentName !== null)
|
||||||
@@ -4602,6 +4637,19 @@ export interface StrategyRoiPerformance {
|
|||||||
volume?: number;
|
volume?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TopAgentsByPnLViewModel {
|
||||||
|
topAgentsByPnL?: AgentPerformance[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentPerformance {
|
||||||
|
agentName?: string | null;
|
||||||
|
pnL?: number;
|
||||||
|
totalROI?: number;
|
||||||
|
totalVolume?: number;
|
||||||
|
activeStrategiesCount?: number;
|
||||||
|
totalBalance?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserStrategyDetailsViewModel {
|
export interface UserStrategyDetailsViewModel {
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
state?: BotStatus;
|
state?: BotStatus;
|
||||||
|
|||||||
@@ -957,6 +957,19 @@ export interface StrategyRoiPerformance {
|
|||||||
volume?: number;
|
volume?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TopAgentsByPnLViewModel {
|
||||||
|
topAgentsByPnL?: AgentPerformance[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentPerformance {
|
||||||
|
agentName?: string | null;
|
||||||
|
pnL?: number;
|
||||||
|
totalROI?: number;
|
||||||
|
totalVolume?: number;
|
||||||
|
activeStrategiesCount?: number;
|
||||||
|
totalBalance?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserStrategyDetailsViewModel {
|
export interface UserStrategyDetailsViewModel {
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
state?: BotStatus;
|
state?: BotStatus;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ function PlatformSummary({index}: { index: number }) {
|
|||||||
const platformData = data?.platform
|
const platformData = data?.platform
|
||||||
const topStrategies = data?.topStrategies
|
const topStrategies = data?.topStrategies
|
||||||
const topStrategiesByRoi = data?.topStrategiesByRoi
|
const topStrategiesByRoi = data?.topStrategiesByRoi
|
||||||
|
const topAgentsByPnL = data?.topAgentsByPnL
|
||||||
|
|
||||||
const formatCurrency = (value: number) => {
|
const formatCurrency = (value: number) => {
|
||||||
if (value >= 1000000) {
|
if (value >= 1000000) {
|
||||||
@@ -210,6 +211,46 @@ function PlatformSummary({index}: { index: number }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Top 3 Agents by PnL */}
|
||||||
|
<div className="bg-base-200 rounded-lg p-6">
|
||||||
|
<div className="flex items-center gap-2 mb-4">
|
||||||
|
<span className="text-2xl">👥</span>
|
||||||
|
<h3 className="text-lg font-semibold text-gray-400">Top 3 Agents by PnL</h3>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{topAgentsByPnL?.topAgentsByPnL?.slice(0, 3).map((agent, index) => (
|
||||||
|
<div key={index} className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="w-8 h-8 bg-purple-500 rounded-full flex items-center justify-center">
|
||||||
|
<span className="text-xs font-bold text-white">
|
||||||
|
{agent.agentName?.charAt(0) || 'A'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-sm text-white font-medium">
|
||||||
|
{agent.agentName || '[Agent Name]'}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-400">
|
||||||
|
{agent.activeStrategiesCount || 0} strategies
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">
|
||||||
|
<div
|
||||||
|
className={`text-sm font-bold ${(agent.pnL || 0) >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||||
|
{(agent.pnL || 0) >= 0 ? '+' : ''}{formatCurrency(agent.pnL || 0)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-400">
|
||||||
|
{(agent.totalROI || 0).toFixed(2)}% ROI
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)) || (
|
||||||
|
<div className="text-gray-500 text-sm">No agent data available</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Platform Summary Stats */}
|
{/* Platform Summary Stats */}
|
||||||
|
|||||||
@@ -2,28 +2,32 @@ import {
|
|||||||
DataClient,
|
DataClient,
|
||||||
type PlatformSummaryViewModel,
|
type PlatformSummaryViewModel,
|
||||||
type TopStrategiesByRoiViewModel,
|
type TopStrategiesByRoiViewModel,
|
||||||
type TopStrategiesViewModel
|
type TopStrategiesViewModel,
|
||||||
|
type TopAgentsByPnLViewModel
|
||||||
} from '../generated/ManagingApi'
|
} from '../generated/ManagingApi'
|
||||||
|
|
||||||
export interface PlatformData {
|
export interface PlatformData {
|
||||||
platform: PlatformSummaryViewModel
|
platform: PlatformSummaryViewModel
|
||||||
topStrategies: TopStrategiesViewModel
|
topStrategies: TopStrategiesViewModel
|
||||||
topStrategiesByRoi: TopStrategiesByRoiViewModel
|
topStrategiesByRoi: TopStrategiesByRoiViewModel
|
||||||
|
topAgentsByPnL: TopAgentsByPnLViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchPlatformData = async (apiUrl: string): Promise<PlatformData> => {
|
export const fetchPlatformData = async (apiUrl: string): Promise<PlatformData> => {
|
||||||
const client = new DataClient({}, apiUrl)
|
const client = new DataClient({}, apiUrl)
|
||||||
|
|
||||||
// Fetch all platform data in parallel
|
// Fetch all platform data in parallel
|
||||||
const [platform, topStrategies, topStrategiesByRoi] = await Promise.all([
|
const [platform, topStrategies, topStrategiesByRoi, topAgentsByPnL] = await Promise.all([
|
||||||
client.data_GetPlatformSummary(),
|
client.data_GetPlatformSummary(),
|
||||||
client.data_GetTopStrategies(),
|
client.data_GetTopStrategies(),
|
||||||
client.data_GetTopStrategiesByRoi()
|
client.data_GetTopStrategiesByRoi(),
|
||||||
|
client.data_GetTopAgentsByPnL()
|
||||||
])
|
])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
platform,
|
platform,
|
||||||
topStrategies,
|
topStrategies,
|
||||||
topStrategiesByRoi
|
topStrategiesByRoi,
|
||||||
|
topAgentsByPnL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user