docs: statistiche per anno (trd/PnL%/maxDD) per strategia e mercato nel doc HTML

Ogni card ora include la tabella anno x mercato:
- fade MR01/02/07 (BTC+ETH) e DIP01: calcolate col PATH LIVE (EXIT-16 + trend 3.0),
  trades/PnL per anno di entry, DD per anno su equity compounding pos 0.15 + DD totale
- PR01: matrice anno x 5 coppie, cella = PnL% (n trade, DD anno) + riga TOT
  (pairs_sim espone ora anche yearly_n, modifica non-breaking)
- TR01/ROT02/TSM01: ret%/DD% per anno dall'equity canonica daily 2021+
- SH01: per anno dal walk-forward EXPANDING (regime validato e ora live)
Nota di convenzione su ogni tabella (leva 3x test vs 2x live, fee incluse) +
caveat: finestra canonica dal 2021, anni 2018-2020 mostrati per onesta' storica.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-07 17:32:00 +00:00
parent bc0ad3e86f
commit 2a97294d67
3 changed files with 200 additions and 21 deletions
+4 -2
View File
@@ -51,7 +51,7 @@ def pairs_sim(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72,
split = int(N * split_frac)
fee = 2 * fee_rt * lev # 2 gambe
cap = peak = 1000.0; dd = 0.0; last = -1
trades = wins = 0; rets = []; yearly = {}
trades = wins = 0; rets = []; yearly = {}; yearly_n = {}
eq_ts: list = []; eq_v: list = []
for i in range(n + 1, N - 1):
if i < split or np.isnan(z[i]) or dr[i] > jump_max:
@@ -81,6 +81,7 @@ def pairs_sim(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72,
trades += 1; wins += ret > 0; rets.append(ret * pos); last = j
eq_ts.append(ts.iloc[j]); eq_v.append(cap)
yearly[ts.iloc[i].year] = yearly.get(ts.iloc[i].year, 0.0) + ret * 100
yearly_n[ts.iloc[i].year] = yearly_n.get(ts.iloc[i].year, 0) + 1
yrs_span = (ts.iloc[-1] - ts.iloc[max(split, 0)]).days / 365.25 or 1
sharpe = float(np.mean(rets) / np.std(rets) * np.sqrt(BARS_YEAR / np.mean([max_bars])) ) if len(rets) > 1 and np.std(rets) > 0 else 0.0
# Sharpe annualizzato sul tempo reale: usa rendimenti per-trade scalati alla frequenza media
@@ -90,7 +91,8 @@ def pairs_sim(a, b, tf="1h", n=50, z_in=2.0, z_exit=0.5, max_bars=72,
ret_tot = (cap / 1000 - 1) * 100
cagr = ((cap / 1000) ** (1 / yrs_span) - 1) * 100 if cap > 0 else -100
return dict(trades=trades, win=wins / trades * 100 if trades else 0, ret=ret_tot, cagr=cagr,
dd=dd * 100, sharpe=sharpe, yearly=yearly, eq_ts=eq_ts, eq_v=eq_v)
dd=dd * 100, sharpe=sharpe, yearly=yearly, yearly_n=yearly_n,
eq_ts=eq_ts, eq_v=eq_v)
def check_no_lookahead():