mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-06 20:41:14 +08:00
feat: fix competition chart with accurate PnL calculation and improved UI
Backend: - Add GetByID method to TraderStore for fetching trader without userID - Calculate total_pnl_pct in equity history API using initial_balance - Falls back to first snapshot equity if initial_balance not set Frontend (ComparisonChart): - Redesign with modern UI: gradient fills, glow effects, rounded corners - Add mini stats bar showing all traders with current PnL - Improved tooltip with date, time, and trend icons - Better Y-axis domain calculation ensuring zero is visible - Bottom stats grid: Leader, Lead PnL, Gap, Data Points - Use ComposedChart with Area + Line for visual depth - Animated loading state with spinning indicator
This commit is contained in:
@@ -2248,6 +2248,19 @@ func (s *Server) getEquityHistoryForTraders(traderIDs []string) map[string]inter
|
||||
histories := make(map[string]interface{})
|
||||
errors := make(map[string]string)
|
||||
|
||||
// Pre-fetch initial balances for all traders
|
||||
initialBalances := make(map[string]float64)
|
||||
for _, traderID := range traderIDs {
|
||||
if traderID == "" {
|
||||
continue
|
||||
}
|
||||
// Get trader's initial balance from database (use GetByID which doesn't require userID)
|
||||
trader, err := s.store.Trader().GetByID(traderID)
|
||||
if err == nil && trader != nil && trader.InitialBalance > 0 {
|
||||
initialBalances[traderID] = trader.InitialBalance
|
||||
}
|
||||
}
|
||||
|
||||
for _, traderID := range traderIDs {
|
||||
if traderID == "" {
|
||||
continue
|
||||
@@ -2266,14 +2279,28 @@ func (s *Server) getEquityHistoryForTraders(traderIDs []string) map[string]inter
|
||||
continue
|
||||
}
|
||||
|
||||
// Build return rate historical data
|
||||
// Get initial balance for calculating PnL percentage
|
||||
initialBalance := initialBalances[traderID]
|
||||
if initialBalance <= 0 {
|
||||
// If no initial balance configured, use the first snapshot's equity as baseline
|
||||
initialBalance = snapshots[0].TotalEquity
|
||||
}
|
||||
|
||||
// Build return rate historical data with PnL percentage
|
||||
history := make([]map[string]interface{}, 0, len(snapshots))
|
||||
for _, snap := range snapshots {
|
||||
// Calculate PnL percentage: (current_equity - initial_balance) / initial_balance * 100
|
||||
pnlPct := 0.0
|
||||
if initialBalance > 0 {
|
||||
pnlPct = (snap.TotalEquity - initialBalance) / initialBalance * 100
|
||||
}
|
||||
|
||||
history = append(history, map[string]interface{}{
|
||||
"timestamp": snap.Timestamp,
|
||||
"total_equity": snap.TotalEquity,
|
||||
"total_pnl": snap.UnrealizedPnL,
|
||||
"balance": snap.Balance,
|
||||
"timestamp": snap.Timestamp,
|
||||
"total_equity": snap.TotalEquity,
|
||||
"total_pnl": snap.UnrealizedPnL,
|
||||
"total_pnl_pct": pnlPct,
|
||||
"balance": snap.Balance,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user