Add detailed PnL and duration stats to dashboard
This commit is contained in:
@@ -753,6 +753,62 @@ func (t *Trader) GetClosedStats() (converged, diverged, flat, total int) {
|
||||
return
|
||||
}
|
||||
|
||||
// GetDetailedStats returns comprehensive trading statistics.
|
||||
type DetailedStats struct {
|
||||
TotalTrades int `json:"total_trades"`
|
||||
TotalPnlPct float64 `json:"total_pnl_pct"`
|
||||
AvgPnlPct float64 `json:"avg_pnl_pct"`
|
||||
MaxProfitPct float64 `json:"max_profit_pct"`
|
||||
MaxLossPct float64 `json:"max_loss_pct"`
|
||||
AvgDuration string `json:"avg_duration"`
|
||||
TotalDuration string `json:"total_duration"`
|
||||
WinningTrades int `json:"winning_trades"`
|
||||
LosingTrades int `json:"losing_trades"`
|
||||
WinRate float64 `json:"win_rate"`
|
||||
}
|
||||
|
||||
func (t *Trader) GetDetailedStats() DetailedStats {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
ds := DetailedStats{}
|
||||
if len(t.closedTrades) == 0 {
|
||||
return ds
|
||||
}
|
||||
var totalDur time.Duration
|
||||
ds.MaxLossPct = 1e9 // sentinel
|
||||
for _, tr := range t.closedTrades {
|
||||
ds.TotalTrades++
|
||||
ds.TotalPnlPct += tr.PnlPct
|
||||
if tr.PnlPct >= 0 {
|
||||
ds.WinningTrades++
|
||||
if tr.PnlPct > ds.MaxProfitPct {
|
||||
ds.MaxProfitPct = tr.PnlPct
|
||||
}
|
||||
} else {
|
||||
ds.LosingTrades++
|
||||
if tr.PnlPct < ds.MaxLossPct {
|
||||
ds.MaxLossPct = tr.PnlPct
|
||||
}
|
||||
}
|
||||
if !tr.ClosedAt.IsZero() && !tr.OpenedAt.IsZero() {
|
||||
totalDur += tr.ClosedAt.Sub(tr.OpenedAt)
|
||||
}
|
||||
}
|
||||
if ds.MaxLossPct == 1e9 {
|
||||
ds.MaxLossPct = 0
|
||||
}
|
||||
if ds.TotalTrades > 0 {
|
||||
ds.AvgPnlPct = ds.TotalPnlPct / float64(ds.TotalTrades)
|
||||
ds.WinRate = float64(ds.WinningTrades) / float64(ds.TotalTrades) * 100
|
||||
}
|
||||
if totalDur > 0 {
|
||||
avgDur := totalDur / time.Duration(ds.TotalTrades)
|
||||
ds.AvgDuration = avgDur.Round(time.Second).String()
|
||||
ds.TotalDuration = totalDur.Round(time.Second).String()
|
||||
}
|
||||
return ds
|
||||
}
|
||||
|
||||
// GetClosedTrades returns the full closed trade history.
|
||||
func (t *Trader) GetClosedTrades() []TradeRecord {
|
||||
t.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user