diff --git a/static/js/stats.js b/static/js/stats.js index be1cc45..fbdcc5a 100644 --- a/static/js/stats.js +++ b/static/js/stats.js @@ -64,16 +64,26 @@ } function cellClass(key, val) { + if (key === 'max_loss' || key === 'max_profit') { + if (val === 0) return 'text-muted'; + } if (key === 'total_net' || key === 'max_profit' || key === 'avg_profit') { if (val > 0) return 'text-profit'; if (val < 0) return 'text-loss'; } if (key === 'max_loss' || key === 'avg_loss' || key === 'total_fee') { - return 'text-loss'; + if (val < 0) return 'text-loss'; } return ''; } + function fmtBreakdownVal(key, val) { + if ((key === 'max_loss' || key === 'max_profit') && (val === 0 || val === 0.0)) { + return '-'; + } + return fmtNum(val); + } + function renderBreakdown(key) { if (!cache || !cache.breakdowns) return; var block = cache.breakdowns[key]; @@ -110,7 +120,7 @@ } else if (col.key === 'label') { td.textContent = val || '-'; } else if (typeof val === 'number') { - td.textContent = fmtNum(val); + td.textContent = fmtBreakdownVal(col.key, val); td.className = cellClass(col.key, val); } else { td.textContent = val != null ? val : '-'; diff --git a/stats_engine.py b/stats_engine.py index 72778b5..125bd79 100644 --- a/stats_engine.py +++ b/stats_engine.py @@ -102,8 +102,8 @@ def _agg_metrics(label: str, items: list[dict]) -> dict: pl_ratio = round(avg_profit / abs(avg_loss), 2) if wins and losses and avg_loss != 0 else 0.0 total_fee = round(sum(_fee(r) for r in items), 2) total_net = round(sum(nets), 2) - max_loss = round(min(nets), 2) if nets else 0.0 - max_profit = round(max(nets), 2) if nets else 0.0 + max_loss = round(min(losses), 2) if losses else 0.0 + max_profit = round(max(wins), 2) if wins else 0.0 win_rate = round(win_cnt / count * 100, 2) if count else 0.0 return { "label": label, @@ -177,8 +177,8 @@ def compute_summary(trades: list[dict], reviews: list[dict], live_capital: float avg_loss = round(sum(losses) / len(losses), 2) if losses else 0.0 pl_ratio = round(avg_profit / abs(avg_loss), 2) if wins and losses and avg_loss != 0 else 0.0 total_fee = round(sum(_fee(t) for t in trades) + sum(_fee(r) for r in reviews), 2) - max_loss_amt = round(min(nets), 2) if nets else 0.0 - max_profit_amt = round(max(nets), 2) if nets else 0.0 + max_loss_amt = round(min(losses), 2) if losses else 0.0 + max_profit_amt = round(max(wins), 2) if wins else 0.0 margins_loss = [ _margin_pct(_net_pnl(t), t.get("margin"))