Files
ftdt-quant-lab/common/metrics.py
T
ramseshk 4457cdffc5 Comprehensive fix: live node resilience + CSS contrast + win_rate + equity curves
- Mainnet API fallback when testnet unavailable (prices, orderbook, instruments)
- Bypassed broken SDK instrument loading, uses raw mainnet meta API
- Dynamic BTC/ETH perp ID lookup (handles "-USD-PERP" suffix changes)
- Strategy-level equity tracking for per-strategy detail charts
- Win rate fixed: checks pnl_net/pnl_gross not just pnl field
- CSS contrast improved: --tx #6b6b7b→#9e9eae, borders/highlights brightened
- Equity curve recalculated on fee tier change (chart adjusts visually)
- Added Open Positions & Orders panel placeholder
2026-08-05 02:53:31 +00:00

45 lines
1.2 KiB
Python

"""
Performance metrics.
Sharpe ratio, Sortino ratio, max drawdown, win rate.
Standard toolbox for evaluating a trading strategy.
"""
import numpy as np
def sharpe(returns: list[float], rf: float = 0.0, periods: int = 365) -> float:
if len(returns) < 2:
return 0.0
excess = np.mean(returns) - rf
std = np.std(returns, ddof=1)
return (excess / std) * np.sqrt(periods) if std > 0 else 0.0
def sortino(returns: list[float], rf: float = 0.0, periods: int = 365) -> float:
if len(returns) < 2:
return 0.0
excess = np.mean(returns) - rf
downside = [r for r in returns if r < 0]
d_std = np.std(downside, ddof=1) if downside else 0.0
return (excess / d_std) * np.sqrt(periods) if d_std > 0 else 0.0
def max_drawdown(equity: list[float]) -> float:
if not equity:
return 0.0
peak = equity[0]
worst = 0.0
for v in equity:
if v > peak:
peak = v
dd = (peak - v) / peak if peak > 0 else 0.0
worst = max(worst, dd)
return worst
def win_rate(trades: list[dict]) -> float:
if not trades:
return 0.0
tp = sum(1 for t in trades if (t.get("pnl_net") or t.get("pnl_gross") or t.get("pnl", 0)) > 0)
return tp / len(trades)