Add net Pnl in db
This commit is contained in:
@@ -346,6 +346,7 @@ public class DataController : ControllerBase
|
||||
{
|
||||
StrategyName = bot.Name,
|
||||
PnL = bot.Pnl,
|
||||
NetPnL = bot.NetPnL,
|
||||
AgentName = bot.User.AgentName,
|
||||
})
|
||||
.ToList()
|
||||
@@ -373,6 +374,7 @@ public class DataController : ControllerBase
|
||||
StrategyName = bot.Name,
|
||||
Roi = bot.Roi,
|
||||
PnL = bot.Pnl,
|
||||
NetPnL = bot.NetPnL,
|
||||
Volume = bot.Volume
|
||||
})
|
||||
.ToList()
|
||||
@@ -393,10 +395,10 @@ public class DataController : ControllerBase
|
||||
// Get all agent summaries
|
||||
var allAgentSummaries = await _mediator.Send(new GetAllAgentSummariesCommand());
|
||||
|
||||
// Filter agents with valid PnL data and order by PnL
|
||||
// Filter agents with valid PnL data and order by NetPnL
|
||||
var agentsWithPnL = allAgentSummaries
|
||||
.Where(agent => agent.TotalPnL != 0) // Only include agents with actual PnL
|
||||
.OrderByDescending(agent => agent.TotalPnL)
|
||||
.Where(agent => agent.NetPnL != 0) // Only include agents with actual NetPnL
|
||||
.OrderByDescending(agent => agent.NetPnL)
|
||||
.Take(3)
|
||||
.ToList();
|
||||
|
||||
@@ -408,6 +410,7 @@ public class DataController : ControllerBase
|
||||
{
|
||||
AgentName = agent.AgentName,
|
||||
PnL = agent.TotalPnL,
|
||||
NetPnL = agent.NetPnL,
|
||||
TotalROI = agent.TotalROI,
|
||||
TotalVolume = agent.TotalVolume,
|
||||
ActiveStrategiesCount = agent.ActiveStrategiesCount,
|
||||
@@ -521,6 +524,7 @@ public class DataController : ControllerBase
|
||||
Name = strategy.Name,
|
||||
State = strategy.Status,
|
||||
PnL = strategy.Pnl,
|
||||
NetPnL = strategy.NetPnL,
|
||||
ROIPercentage = strategy.Roi,
|
||||
Runtime = strategy.StartupTime,
|
||||
WinRate = winRate,
|
||||
@@ -579,7 +583,7 @@ public class DataController : ControllerBase
|
||||
public async Task<ActionResult<PaginatedAgentIndexResponse>> GetAgentIndexPaginated(
|
||||
int page = 1,
|
||||
int pageSize = 10,
|
||||
SortableFields sortBy = SortableFields.TotalPnL,
|
||||
SortableFields sortBy = SortableFields.NetPnL,
|
||||
string sortOrder = "desc",
|
||||
string? agentNames = null)
|
||||
{
|
||||
@@ -632,6 +636,7 @@ public class DataController : ControllerBase
|
||||
{
|
||||
AgentName = agentSummary.AgentName,
|
||||
TotalPnL = agentSummary.TotalPnL,
|
||||
NetPnL = agentSummary.NetPnL,
|
||||
TotalROI = agentSummary.TotalROI,
|
||||
Wins = agentSummary.Wins,
|
||||
Losses = agentSummary.Losses,
|
||||
@@ -799,6 +804,7 @@ public class DataController : ControllerBase
|
||||
TotalStrategies = s.TotalStrategies,
|
||||
TotalVolume = s.TotalVolume,
|
||||
TotalPnL = s.TotalPnL,
|
||||
NetPnL = s.NetPnL,
|
||||
TotalOpenInterest = s.TotalOpenInterest,
|
||||
TotalPositionCount = s.TotalLifetimePositionCount
|
||||
})
|
||||
|
||||
@@ -13,10 +13,15 @@ namespace Managing.Api.Models.Responses
|
||||
public string AgentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total profit and loss in USD
|
||||
/// Total profit and loss in USD (gross, before fees)
|
||||
/// </summary>
|
||||
public decimal TotalPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net profit and loss in USD (after fees)
|
||||
/// </summary>
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total return on investment as a percentage
|
||||
/// </summary>
|
||||
@@ -160,10 +165,15 @@ namespace Managing.Api.Models.Responses
|
||||
public required decimal TotalVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total PnL on this date in USD
|
||||
/// Total PnL on this date in USD (gross, before fees)
|
||||
/// </summary>
|
||||
public required decimal TotalPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net PnL on this date in USD (after fees)
|
||||
/// </summary>
|
||||
public required decimal NetPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total open interest on this date in USD
|
||||
/// </summary>
|
||||
|
||||
@@ -50,7 +50,7 @@ public class PaginatedAgentIndexResponse
|
||||
/// <summary>
|
||||
/// Field used for sorting
|
||||
/// </summary>
|
||||
public SortableFields SortBy { get; set; } = SortableFields.TotalPnL;
|
||||
public SortableFields SortBy { get; set; } = SortableFields.NetPnL;
|
||||
|
||||
/// <summary>
|
||||
/// Sort order (asc or desc)
|
||||
|
||||
@@ -11,10 +11,15 @@ namespace Managing.Api.Models.Responses
|
||||
public string StrategyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profit and Loss value of the strategy
|
||||
/// Profit and Loss value of the strategy (gross, before fees)
|
||||
/// </summary>
|
||||
public decimal PnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net Profit and Loss value of the strategy (after fees)
|
||||
/// </summary>
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
public string AgentName { get; set; }
|
||||
}
|
||||
|
||||
@@ -34,10 +39,15 @@ namespace Managing.Api.Models.Responses
|
||||
public decimal Roi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profit and Loss value of the strategy
|
||||
/// Profit and Loss value of the strategy (gross, before fees)
|
||||
/// </summary>
|
||||
public decimal PnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net Profit and Loss value of the strategy (after fees)
|
||||
/// </summary>
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Volume traded by the strategy
|
||||
/// </summary>
|
||||
@@ -77,10 +87,15 @@ namespace Managing.Api.Models.Responses
|
||||
public string AgentName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profit and Loss value of the agent
|
||||
/// Profit and Loss value of the agent (gross, before fees)
|
||||
/// </summary>
|
||||
public decimal PnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net Profit and Loss value of the agent (after fees)
|
||||
/// </summary>
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total ROI percentage of the agent
|
||||
/// </summary>
|
||||
|
||||
@@ -19,10 +19,15 @@ namespace Managing.Api.Models.Responses
|
||||
public Enums.BotStatus State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total profit or loss generated by the strategy in USD
|
||||
/// Total profit or loss generated by the strategy in USD (gross, before fees)
|
||||
/// </summary>
|
||||
public decimal PnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Net profit or loss generated by the strategy in USD (after fees)
|
||||
/// </summary>
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return on investment percentage
|
||||
/// </summary>
|
||||
|
||||
@@ -22,27 +22,29 @@ public class PlatformSummaryGrainState
|
||||
|
||||
[Id(5)] public decimal TotalPlatformPnL { get; set; }
|
||||
|
||||
[Id(6)] public decimal TotalPlatformVolume { get; set; }
|
||||
[Id(6)] public decimal NetPnL { get; set; }
|
||||
|
||||
[Id(7)] public decimal OpenInterest { get; set; }
|
||||
[Id(7)] public decimal TotalPlatformVolume { get; set; }
|
||||
|
||||
[Id(8)] public int TotalLifetimePositionCount { get; set; }
|
||||
[Id(8)] public decimal OpenInterest { get; set; }
|
||||
|
||||
[Id(9)] public decimal TotalPlatformFees { get; set; }
|
||||
[Id(9)] public int TotalLifetimePositionCount { get; set; }
|
||||
|
||||
[Id(10)] public decimal TotalPlatformFees { get; set; }
|
||||
|
||||
// Historical snapshots
|
||||
[Id(10)] public List<DailySnapshot> DailySnapshots { get; set; } = new();
|
||||
[Id(11)] public List<DailySnapshot> DailySnapshots { get; set; } = new();
|
||||
|
||||
// Volume breakdown by asset
|
||||
[Id(11)] public Dictionary<Ticker, decimal> VolumeByAsset { get; set; } = new();
|
||||
[Id(12)] public Dictionary<Ticker, decimal> VolumeByAsset { get; set; } = new();
|
||||
|
||||
// Position count breakdown
|
||||
[Id(12)] public Dictionary<Ticker, int> PositionCountByAsset { get; set; } = new();
|
||||
[Id(13)] public Dictionary<Ticker, int> PositionCountByAsset { get; set; } = new();
|
||||
|
||||
[Id(13)] public Dictionary<TradeDirection, int> PositionCountByDirection { get; set; } = new();
|
||||
[Id(14)] public Dictionary<TradeDirection, int> PositionCountByDirection { get; set; } = new();
|
||||
|
||||
// Flag to track if volume has been updated by events (not from bot strategies)
|
||||
[Id(14)] public bool VolumeUpdatedByEvents { get; set; }
|
||||
[Id(15)] public bool VolumeUpdatedByEvents { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -61,9 +63,11 @@ public class DailySnapshot
|
||||
|
||||
[Id(4)] public decimal TotalPnL { get; set; }
|
||||
|
||||
[Id(5)] public decimal TotalOpenInterest { get; set; }
|
||||
[Id(5)] public decimal NetPnL { get; set; }
|
||||
|
||||
[Id(6)] public int TotalLifetimePositionCount { get; set; }
|
||||
[Id(6)] public decimal TotalOpenInterest { get; set; }
|
||||
|
||||
[Id(7)] public int TotalPlatformFees { get; set; }
|
||||
[Id(7)] public int TotalLifetimePositionCount { get; set; }
|
||||
|
||||
[Id(8)] public int TotalPlatformFees { get; set; }
|
||||
}
|
||||
@@ -237,7 +237,8 @@ public class AgentGrain : Grain, IAgentGrain
|
||||
{
|
||||
UserId = (int)this.GetPrimaryKeyLong(),
|
||||
AgentName = _state.State.AgentName,
|
||||
TotalPnL = totalPnL, // Use net PnL without fees
|
||||
TotalPnL = totalPnL, // Gross PnL before fees
|
||||
NetPnL = netPnL, // Net PnL after fees
|
||||
Wins = totalWins,
|
||||
Losses = totalLosses,
|
||||
TotalROI = totalROI,
|
||||
|
||||
@@ -720,12 +720,13 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
var (tradeWins, tradeLosses) = TradingBox.GetWinLossCount(_tradingBot.Positions);
|
||||
var pnl = _tradingBot.GetProfitAndLoss();
|
||||
var fees = _tradingBot.GetTotalFees();
|
||||
var netPnl = pnl - fees; // Net PnL after fees
|
||||
var volume = TradingBox.GetTotalVolumeTraded(_tradingBot.Positions);
|
||||
|
||||
// Calculate ROI based on total investment (PnL minus fees)
|
||||
// Calculate ROI based on total investment (Net PnL)
|
||||
var totalInvestment = _tradingBot.Positions.Values
|
||||
.Sum(p => p.Open.Quantity * p.Open.Price);
|
||||
var roi = totalInvestment > 0 ? ((pnl - fees) / totalInvestment) * 100 : 0;
|
||||
var roi = totalInvestment > 0 ? (netPnl / totalInvestment) * 100 : 0;
|
||||
|
||||
// Calculate long and short position counts
|
||||
var longPositionCount = _tradingBot.Positions.Values
|
||||
@@ -745,7 +746,8 @@ public class LiveTradingBotGrain : Grain, ILiveTradingBotGrain, IRemindable
|
||||
CreateDate = _state.State.CreateDate,
|
||||
TradeWins = tradeWins,
|
||||
TradeLosses = tradeLosses,
|
||||
Pnl = pnl,
|
||||
Pnl = pnl, // Gross PnL before fees
|
||||
NetPnL = netPnl, // Net PnL after fees
|
||||
Roi = roi,
|
||||
Volume = volume,
|
||||
Fees = fees,
|
||||
|
||||
@@ -68,6 +68,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
TotalStrategies = 0,
|
||||
TotalVolume = 0,
|
||||
TotalPnL = 0,
|
||||
NetPnL = 0,
|
||||
TotalOpenInterest = 0,
|
||||
TotalLifetimePositionCount = 0,
|
||||
TotalPlatformFees = 0,
|
||||
@@ -170,6 +171,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
_state.State.TotalPlatformVolume = totalVolume;
|
||||
_state.State.TotalPlatformFees = totalFees;
|
||||
_state.State.TotalPlatformPnL = totalPnL;
|
||||
_state.State.NetPnL = totalPnL - totalFees; // Calculate NetPnL
|
||||
_state.State.OpenInterest = totalOpenInterest;
|
||||
_state.State.TotalLifetimePositionCount = totalPositionCount;
|
||||
_state.State.HasPendingChanges = false;
|
||||
@@ -289,6 +291,7 @@ public class PlatformSummaryGrain : Grain, IPlatformSummaryGrain, IRemindable
|
||||
TotalStrategies = _state.State.TotalActiveStrategies,
|
||||
TotalVolume = _state.State.TotalPlatformVolume,
|
||||
TotalPnL = _state.State.TotalPlatformPnL,
|
||||
NetPnL = _state.State.NetPnL,
|
||||
TotalOpenInterest = _state.State.OpenInterest,
|
||||
TotalLifetimePositionCount = _state.State.TotalLifetimePositionCount,
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Managing.Application.ManageBot.Commands
|
||||
public GetPaginatedAgentSummariesCommand(
|
||||
int page = 1,
|
||||
int pageSize = 10,
|
||||
SortableFields sortBy = SortableFields.TotalPnL,
|
||||
SortableFields sortBy = SortableFields.NetPnL,
|
||||
string sortOrder = "desc",
|
||||
IEnumerable<string>? agentNames = null)
|
||||
{
|
||||
|
||||
@@ -477,7 +477,7 @@ public static class Enums
|
||||
/// </summary>
|
||||
public enum SortableFields
|
||||
{
|
||||
TotalPnL,
|
||||
NetPnL,
|
||||
TotalROI,
|
||||
Wins,
|
||||
Losses,
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Managing.Domain.Bots
|
||||
public int TradeWins { get; set; }
|
||||
public int TradeLosses { get; set; }
|
||||
public decimal Pnl { get; set; }
|
||||
public decimal NetPnL { get; set; }
|
||||
public decimal Roi { get; set; }
|
||||
public decimal Volume { get; set; }
|
||||
public decimal Fees { get; set; }
|
||||
|
||||
@@ -50,4 +50,7 @@ public class AgentSummary
|
||||
|
||||
[Id(14)]
|
||||
public decimal TotalFees { get; set; }
|
||||
|
||||
[Id(15)]
|
||||
public decimal NetPnL { get; set; }
|
||||
}
|
||||
1445
src/Managing.Infrastructure.Database/Migrations/20250928144516_AddNetPnLToAgentSummary.Designer.cs
generated
Normal file
1445
src/Managing.Infrastructure.Database/Migrations/20250928144516_AddNetPnLToAgentSummary.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Managing.Infrastructure.Databases.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddNetPnLToAgentSummary : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "NetPnL",
|
||||
table: "AgentSummaries",
|
||||
type: "numeric",
|
||||
nullable: false,
|
||||
defaultValue: 0m);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "NetPnL",
|
||||
table: "AgentSummaries");
|
||||
}
|
||||
}
|
||||
}
|
||||
1449
src/Managing.Infrastructure.Database/Migrations/20250928145325_AddNetPnLToBot.Designer.cs
generated
Normal file
1449
src/Managing.Infrastructure.Database/Migrations/20250928145325_AddNetPnLToBot.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Managing.Infrastructure.Databases.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddNetPnLToBot : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "NetPnL",
|
||||
table: "Bots",
|
||||
type: "numeric(18,8)",
|
||||
precision: 18,
|
||||
scale: 8,
|
||||
nullable: false,
|
||||
defaultValue: 0m);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "NetPnL",
|
||||
table: "Bots");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,9 @@ namespace Managing.Infrastructure.Databases.Migrations
|
||||
b.Property<int>("Losses")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("NetPnL")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.Property<DateTime?>("Runtime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
@@ -250,6 +253,10 @@ namespace Managing.Infrastructure.Databases.Migrations
|
||||
.HasMaxLength(255)
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<decimal>("NetPnL")
|
||||
.HasPrecision(18, 8)
|
||||
.HasColumnType("numeric(18,8)");
|
||||
|
||||
b.Property<decimal>("Pnl")
|
||||
.HasPrecision(18, 8)
|
||||
.HasColumnType("numeric(18,8)");
|
||||
|
||||
@@ -189,9 +189,9 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
||||
var isDescending = sortOrder.ToLowerInvariant() == "desc";
|
||||
query = sortBy switch
|
||||
{
|
||||
SortableFields.TotalPnL => isDescending
|
||||
? query.OrderByDescending(a => a.TotalPnL)
|
||||
: query.OrderBy(a => a.TotalPnL),
|
||||
SortableFields.NetPnL => isDescending
|
||||
? query.OrderByDescending(a => a.NetPnL)
|
||||
: query.OrderBy(a => a.NetPnL),
|
||||
SortableFields.TotalROI => isDescending
|
||||
? query.OrderByDescending(a => a.TotalROI)
|
||||
: query.OrderBy(a => a.TotalROI),
|
||||
@@ -241,6 +241,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
||||
UserId = domain.UserId,
|
||||
AgentName = domain.AgentName,
|
||||
TotalPnL = domain.TotalPnL,
|
||||
NetPnL = domain.NetPnL,
|
||||
TotalROI = domain.TotalROI,
|
||||
Wins = domain.Wins,
|
||||
Losses = domain.Losses,
|
||||
@@ -259,6 +260,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
||||
entity.UserId = domain.UserId;
|
||||
entity.AgentName = domain.AgentName;
|
||||
entity.TotalPnL = domain.TotalPnL;
|
||||
entity.NetPnL = domain.NetPnL;
|
||||
entity.TotalROI = domain.TotalROI;
|
||||
entity.Wins = domain.Wins;
|
||||
entity.Losses = domain.Losses;
|
||||
@@ -277,6 +279,7 @@ public class AgentSummaryRepository : IAgentSummaryRepository
|
||||
UserId = entity.UserId,
|
||||
AgentName = entity.AgentName,
|
||||
TotalPnL = entity.TotalPnL,
|
||||
NetPnL = entity.NetPnL,
|
||||
TotalROI = entity.TotalROI,
|
||||
Wins = entity.Wins,
|
||||
Losses = entity.Losses,
|
||||
|
||||
@@ -16,6 +16,7 @@ public class AgentSummaryEntity
|
||||
public decimal TotalVolume { get; set; }
|
||||
public decimal TotalBalance { get; set; }
|
||||
public decimal TotalFees { get; set; }
|
||||
public decimal NetPnL { get; set; }
|
||||
|
||||
// Navigation property
|
||||
public UserEntity User { get; set; }
|
||||
|
||||
@@ -24,6 +24,7 @@ public class BotEntity
|
||||
public int TradeWins { get; set; }
|
||||
public int TradeLosses { get; set; }
|
||||
public decimal Pnl { get; set; }
|
||||
public decimal NetPnL { get; set; }
|
||||
public decimal Roi { get; set; }
|
||||
public decimal Volume { get; set; }
|
||||
public decimal Fees { get; set; }
|
||||
|
||||
@@ -447,6 +447,7 @@ public class ManagingDbContext : DbContext
|
||||
entity.Property(e => e.TradeWins).IsRequired();
|
||||
entity.Property(e => e.TradeLosses).IsRequired();
|
||||
entity.Property(e => e.Pnl).HasPrecision(18, 8);
|
||||
entity.Property(e => e.NetPnL).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Roi).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Volume).HasPrecision(18, 8);
|
||||
entity.Property(e => e.Fees).HasPrecision(18, 8);
|
||||
|
||||
@@ -69,6 +69,7 @@ public class PostgreSqlBotRepository : IBotRepository
|
||||
existingEntity.TradeWins = bot.TradeWins;
|
||||
existingEntity.TradeLosses = bot.TradeLosses;
|
||||
existingEntity.Pnl = bot.Pnl;
|
||||
existingEntity.NetPnL = bot.NetPnL;
|
||||
existingEntity.Roi = bot.Roi;
|
||||
existingEntity.Volume = bot.Volume;
|
||||
existingEntity.Fees = bot.Fees;
|
||||
|
||||
@@ -694,6 +694,7 @@ public static class PostgreSqlMappers
|
||||
TradeWins = entity.TradeWins,
|
||||
TradeLosses = entity.TradeLosses,
|
||||
Pnl = entity.Pnl,
|
||||
NetPnL = entity.NetPnL,
|
||||
Roi = entity.Roi,
|
||||
Volume = entity.Volume,
|
||||
Fees = entity.Fees,
|
||||
@@ -720,6 +721,7 @@ public static class PostgreSqlMappers
|
||||
TradeWins = bot.TradeWins,
|
||||
TradeLosses = bot.TradeLosses,
|
||||
Pnl = bot.Pnl,
|
||||
NetPnL = bot.NetPnL,
|
||||
Roi = bot.Roi,
|
||||
Volume = bot.Volume,
|
||||
Fees = bot.Fees,
|
||||
|
||||
@@ -3563,6 +3563,7 @@ export class UserClient extends AuthorizedApiBase {
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
id?: number;
|
||||
name: string;
|
||||
exchange: TradingExchanges;
|
||||
type: AccountType;
|
||||
@@ -3909,8 +3910,8 @@ export enum SignalType {
|
||||
}
|
||||
|
||||
export interface Position {
|
||||
accountName: string;
|
||||
date: Date;
|
||||
accountId: number;
|
||||
originDirection: TradeDirection;
|
||||
ticker: Ticker;
|
||||
moneyManagement: LightMoneyManagement;
|
||||
@@ -3919,6 +3920,8 @@ export interface Position {
|
||||
TakeProfit1: Trade;
|
||||
TakeProfit2?: Trade | null;
|
||||
ProfitAndLoss?: ProfitAndLoss | null;
|
||||
uiFees?: number;
|
||||
gasFees?: number;
|
||||
status: PositionStatus;
|
||||
signalIdentifier?: string | null;
|
||||
identifier: string;
|
||||
@@ -3982,7 +3985,6 @@ export enum PositionStatus {
|
||||
Canceled = "Canceled",
|
||||
Rejected = "Rejected",
|
||||
Updating = "Updating",
|
||||
PartiallyFilled = "PartiallyFilled",
|
||||
Filled = "Filled",
|
||||
Flipped = "Flipped",
|
||||
Finished = "Finished",
|
||||
@@ -4502,6 +4504,7 @@ export interface TopStrategiesViewModel {
|
||||
export interface StrategyPerformance {
|
||||
strategyName?: string | null;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
agentName?: string | null;
|
||||
}
|
||||
|
||||
@@ -4513,6 +4516,7 @@ export interface StrategyRoiPerformance {
|
||||
strategyName?: string | null;
|
||||
roi?: number;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
volume?: number;
|
||||
}
|
||||
|
||||
@@ -4523,6 +4527,7 @@ export interface TopAgentsByPnLViewModel {
|
||||
export interface AgentPerformance {
|
||||
agentName?: string | null;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
totalROI?: number;
|
||||
totalVolume?: number;
|
||||
activeStrategiesCount?: number;
|
||||
@@ -4533,6 +4538,7 @@ export interface UserStrategyDetailsViewModel {
|
||||
name?: string | null;
|
||||
state?: BotStatus;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
roiPercentage?: number;
|
||||
runtime?: Date;
|
||||
winRate?: number;
|
||||
@@ -4569,6 +4575,7 @@ export interface DailySnapshot {
|
||||
totalStrategies?: number;
|
||||
totalVolume?: number;
|
||||
totalPnL?: number;
|
||||
netPnL?: number;
|
||||
totalOpenInterest?: number;
|
||||
totalPositionCount?: number;
|
||||
}
|
||||
@@ -4590,16 +4597,18 @@ export interface PaginatedAgentIndexResponse {
|
||||
export interface AgentSummaryViewModel {
|
||||
agentName?: string | null;
|
||||
totalPnL?: number;
|
||||
netPnL?: number;
|
||||
totalROI?: number;
|
||||
wins?: number;
|
||||
losses?: number;
|
||||
activeStrategiesCount?: number;
|
||||
totalVolume?: number;
|
||||
totalBalance?: number;
|
||||
totalFees?: number;
|
||||
}
|
||||
|
||||
export enum SortableFields {
|
||||
TotalPnL = "TotalPnL",
|
||||
NetPnL = "NetPnL",
|
||||
TotalROI = "TotalROI",
|
||||
Wins = "Wins",
|
||||
Losses = "Losses",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
|
||||
export interface Account {
|
||||
id?: number;
|
||||
name: string;
|
||||
exchange: TradingExchanges;
|
||||
type: AccountType;
|
||||
@@ -357,8 +358,8 @@ export enum SignalType {
|
||||
}
|
||||
|
||||
export interface Position {
|
||||
accountName: string;
|
||||
date: Date;
|
||||
accountId: number;
|
||||
originDirection: TradeDirection;
|
||||
ticker: Ticker;
|
||||
moneyManagement: LightMoneyManagement;
|
||||
@@ -367,6 +368,8 @@ export interface Position {
|
||||
TakeProfit1: Trade;
|
||||
TakeProfit2?: Trade | null;
|
||||
ProfitAndLoss?: ProfitAndLoss | null;
|
||||
uiFees?: number;
|
||||
gasFees?: number;
|
||||
status: PositionStatus;
|
||||
signalIdentifier?: string | null;
|
||||
identifier: string;
|
||||
@@ -430,7 +433,6 @@ export enum PositionStatus {
|
||||
Canceled = "Canceled",
|
||||
Rejected = "Rejected",
|
||||
Updating = "Updating",
|
||||
PartiallyFilled = "PartiallyFilled",
|
||||
Filled = "Filled",
|
||||
Flipped = "Flipped",
|
||||
Finished = "Finished",
|
||||
@@ -950,6 +952,7 @@ export interface TopStrategiesViewModel {
|
||||
export interface StrategyPerformance {
|
||||
strategyName?: string | null;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
agentName?: string | null;
|
||||
}
|
||||
|
||||
@@ -961,6 +964,7 @@ export interface StrategyRoiPerformance {
|
||||
strategyName?: string | null;
|
||||
roi?: number;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
volume?: number;
|
||||
}
|
||||
|
||||
@@ -971,6 +975,7 @@ export interface TopAgentsByPnLViewModel {
|
||||
export interface AgentPerformance {
|
||||
agentName?: string | null;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
totalROI?: number;
|
||||
totalVolume?: number;
|
||||
activeStrategiesCount?: number;
|
||||
@@ -981,6 +986,7 @@ export interface UserStrategyDetailsViewModel {
|
||||
name?: string | null;
|
||||
state?: BotStatus;
|
||||
pnL?: number;
|
||||
netPnL?: number;
|
||||
roiPercentage?: number;
|
||||
runtime?: Date;
|
||||
winRate?: number;
|
||||
@@ -1017,6 +1023,7 @@ export interface DailySnapshot {
|
||||
totalStrategies?: number;
|
||||
totalVolume?: number;
|
||||
totalPnL?: number;
|
||||
netPnL?: number;
|
||||
totalOpenInterest?: number;
|
||||
totalPositionCount?: number;
|
||||
}
|
||||
@@ -1038,16 +1045,18 @@ export interface PaginatedAgentIndexResponse {
|
||||
export interface AgentSummaryViewModel {
|
||||
agentName?: string | null;
|
||||
totalPnL?: number;
|
||||
netPnL?: number;
|
||||
totalROI?: number;
|
||||
wins?: number;
|
||||
losses?: number;
|
||||
activeStrategiesCount?: number;
|
||||
totalVolume?: number;
|
||||
totalBalance?: number;
|
||||
totalFees?: number;
|
||||
}
|
||||
|
||||
export enum SortableFields {
|
||||
TotalPnL = "TotalPnL",
|
||||
NetPnL = "NetPnL",
|
||||
TotalROI = "TotalROI",
|
||||
Wins = "Wins",
|
||||
Losses = "Losses",
|
||||
|
||||
@@ -203,8 +203,8 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
<div className="stat-value text-success">{strategyData.winRate || 0}%</div>
|
||||
</div>
|
||||
<div className="stat bg-base-200 rounded-lg">
|
||||
<div className="stat-title">PnL</div>
|
||||
<div className="stat-value text-success">{formatCurrency(strategyData.pnL)}</div>
|
||||
<div className="stat-title">Net PnL</div>
|
||||
<div className="stat-value text-success">{formatCurrency(strategyData.netPnL)}</div>
|
||||
</div>
|
||||
<div className="stat bg-base-200 rounded-lg">
|
||||
<div className="stat-title">Backtest</div>
|
||||
@@ -283,8 +283,8 @@ const AgentStrategy: React.FC<AgentStrategyProps> = ({ index }) => {
|
||||
<div className="card-body">
|
||||
<h3 className="card-title">PnL $</h3>
|
||||
<div className="text-2xl font-bold">{formatCurrency(strategyData.pnL)}</div>
|
||||
<div className="text-sm">
|
||||
{formatCurrency((strategyData.pnL || 0) * 0.1)} Today
|
||||
<div className="text-sm text-gray-400">
|
||||
Net: {formatCurrency(strategyData.netPnL)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -210,8 +210,8 @@ function PlatformSummary({index}: { index: number }) {
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`text-sm font-bold ${strategy.pnL && strategy.pnL >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{strategy.pnL && strategy.pnL >= 0 ? '+' : ''}{formatCurrency(strategy.pnL || 0)}
|
||||
className={`text-sm font-bold ${strategy.netPnL && strategy.netPnL >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{strategy.netPnL && strategy.netPnL >= 0 ? '+' : ''}{formatCurrency(strategy.netPnL || 0)}
|
||||
</div>
|
||||
</div>
|
||||
)) || (
|
||||
@@ -250,8 +250,8 @@ function PlatformSummary({index}: { index: number }) {
|
||||
{(strategy.roi || 0) >= 0 ? '+' : ''}{strategy.roi?.toFixed(2) || 0}%
|
||||
</div>
|
||||
<div
|
||||
className={`text-xs ${(strategy.pnL || 0) >= 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||||
{(strategy.pnL || 0) >= 0 ? '+' : ''}{formatCurrency(strategy.pnL || 0)}
|
||||
className={`text-xs ${(strategy.netPnL || 0) >= 0 ? 'text-green-400' : 'text-red-400'}`}>
|
||||
{(strategy.netPnL || 0) >= 0 ? '+' : ''}{formatCurrency(strategy.netPnL || 0)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -287,8 +287,8 @@ function PlatformSummary({index}: { index: number }) {
|
||||
</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)}
|
||||
className={`text-sm font-bold ${(agent.netPnL || 0) >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{(agent.netPnL || 0) >= 0 ? '+' : ''}{formatCurrency(agent.netPnL || 0)}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
{(agent.totalROI || 0).toFixed(2)}% ROI
|
||||
@@ -332,6 +332,9 @@ function PlatformSummary({index}: { index: number }) {
|
||||
className={`text-3xl font-bold ${(platformData?.totalPlatformPnL || 0) >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{(platformData?.totalPlatformPnL || 0) >= 0 ? '+' : ''}{formatCurrency(platformData?.totalPlatformPnL || 0)}
|
||||
</div>
|
||||
<div className="text-sm text-gray-400 mb-1">
|
||||
Fees: {formatCurrency(platformData?.totalPlatformFees || 0)}
|
||||
</div>
|
||||
<div
|
||||
className={`text-sm ${changesToday.pnLChange >= 0 ? 'text-green-500' : 'text-red-500'}`}>
|
||||
{changesToday.pnLChange >= 0 ? '+' : ''}{formatCurrency(changesToday.pnLChange)} Today
|
||||
|
||||
Reference in New Issue
Block a user