fix: competition chart data sync and display issues

- Add real-time data point to equity history API for chart/leaderboard consistency
- Fix chart legend showing 0% by finding each trader's last available data point
- Use consistent timestamp for all real-time data points in batch requests
- Increase chart trader limit from 5 to 10
- Remove Mini Stats Bar trader limit
This commit is contained in:
tinkle-community
2025-12-11 12:32:04 +08:00
parent 438f55bc30
commit 78b5e73966
3 changed files with 61 additions and 15 deletions

View File

@@ -2505,11 +2505,15 @@ func (s *Server) handleEquityHistoryBatch(c *gin.Context) {
// getEquityHistoryForTraders Get historical data for multiple traders
// Query directly from database, not dependent on trader in memory (so historical data can be retrieved after restart)
// Also appends current real-time data point to ensure chart matches leaderboard
func (s *Server) getEquityHistoryForTraders(traderIDs []string) map[string]interface{} {
result := make(map[string]interface{})
histories := make(map[string]interface{})
errors := make(map[string]string)
// Use a single consistent timestamp for all real-time data points
now := time.Now()
// Pre-fetch initial balances for all traders
initialBalances := make(map[string]float64)
for _, traderID := range traderIDs {
@@ -2535,21 +2539,16 @@ func (s *Server) getEquityHistoryForTraders(traderIDs []string) map[string]inter
continue
}
if len(snapshots) == 0 {
// No historical records, return empty array
histories[traderID] = []map[string]interface{}{}
continue
}
// Get initial balance for calculating PnL percentage
initialBalance := initialBalances[traderID]
if initialBalance <= 0 {
if initialBalance <= 0 && len(snapshots) > 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))
history := make([]map[string]interface{}, 0, len(snapshots)+1)
var lastSnapshotTime time.Time
for _, snap := range snapshots {
// Calculate PnL percentage: (current_equity - initial_balance) / initial_balance * 100
pnlPct := 0.0
@@ -2564,6 +2563,43 @@ func (s *Server) getEquityHistoryForTraders(traderIDs []string) map[string]inter
"total_pnl_pct": pnlPct,
"balance": snap.Balance,
})
if snap.Timestamp.After(lastSnapshotTime) {
lastSnapshotTime = snap.Timestamp
}
}
// Append current real-time data point to ensure chart matches leaderboard
// This ensures the latest point is always current, not from a potentially stale snapshot
if trader, err := s.traderManager.GetTrader(traderID); err == nil {
if accountInfo, err := trader.GetAccountInfo(); err == nil {
// Only append if it's been more than 30 seconds since last snapshot
if now.Sub(lastSnapshotTime) > 30*time.Second {
totalEquity := 0.0
if v, ok := accountInfo["total_equity"].(float64); ok {
totalEquity = v
}
totalPnL := 0.0
if v, ok := accountInfo["total_pnl"].(float64); ok {
totalPnL = v
}
walletBalance := 0.0
if v, ok := accountInfo["wallet_balance"].(float64); ok {
walletBalance = v
}
pnlPct := 0.0
if initialBalance > 0 {
pnlPct = (totalEquity - initialBalance) / initialBalance * 100
}
history = append(history, map[string]interface{}{
"timestamp": now,
"total_equity": totalEquity,
"total_pnl": totalPnL,
"total_pnl_pct": pnlPct,
"balance": walletBalance,
})
}
}
}
histories[traderID] = history