docs: aggiorna CLAUDE.md + strategie_attive.html col BLEND ETH/BTC 15m
- CLAUDE.md: default PORT06 (FULL 7.20/OOS 9.66, 18 sleeve), paragrafo BLEND 15m flat-skip (origine gioco Blind Traders, gate, validazione, caveat slippage), copertura reale ~83% (6 pairs), scripts/games/ + pairs15m_* nella struttura. - make_strategy_doc.py: header dinamico dal backtest, colonna ETH/BTC·15m nella tabella pairs, card PR01 col blend, conteggi sleeve aggiornati -> rigenerato HTML. - pairs_sim_flat: ritorna yearly_n (parita' con pairs_sim, usato dal doc). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -495,9 +495,14 @@ def stats_pairs():
|
||||
from scripts.analysis.pairs_research import pairs_sim
|
||||
from scripts.strategies.PR01_pairs_reversion import PAIRS as PAIRS_CFG
|
||||
cols, data = [], {}
|
||||
for a, b, p in PAIRS_CFG:
|
||||
r = pairs_sim(a, b, **p)
|
||||
tag = f"{a}/{b}"
|
||||
from scripts.analysis.pairs_research import pairs_sim_flat
|
||||
# le 5 coppie 1h universali + il BLEND ETH/BTC 15m flat-skip (mezza size = sleeve live)
|
||||
runs = [(f"{a}/{b}", lambda a=a, b=b, p=p: pairs_sim(a, b, **p)) for a, b, p in PAIRS_CFG]
|
||||
runs.append(("ETH/BTC·15m", lambda: pairs_sim_flat(
|
||||
"ETH", "BTC", tf="15m", n=66, z_in=1.674, z_exit=1.0, max_bars=35,
|
||||
flat_skip=True, pos=0.075)))
|
||||
for tag, fn in runs:
|
||||
r = fn()
|
||||
cols.append(tag)
|
||||
s = pd.Series(r["eq_v"], index=pd.to_datetime(r["eq_ts"], utc=True))
|
||||
ydd = {int(y): float(((g.cummax() - g) / g.cummax()).max() * 100)
|
||||
@@ -627,6 +632,12 @@ def main():
|
||||
g_tsm = chart_tsm01(panel)
|
||||
g_sh = chart_sh01()
|
||||
|
||||
# metriche canoniche del default per l'intestazione (sempre aggiornate)
|
||||
pr = PORTFOLIOS["PORT06"].backtest()
|
||||
n_def = len(PORTFOLIOS["PORT06"].sleeve_ids)
|
||||
hdr = (f"FULL Sharpe {pr.full['sharpe']:.2f} / DD {pr.full['dd']:.2f}% — "
|
||||
f"OOS Sharpe {pr.oos['sharpe']:.2f} / DD {pr.oos['dd']:.2f}%")
|
||||
|
||||
B = lambda f, t: f'<span class="badge b-{f}">{t}</span>'
|
||||
real = B("real", "ESECUZIONE REALE (testnet)")
|
||||
sim = B("sim", "SIMULATO")
|
||||
@@ -671,13 +682,19 @@ le fade per costruzione non prendono. Valuta solo barre 4h COMPLETE.</p>""", g_t
|
||||
(solo se positive), gross 0.45. Gate di regime: tutto cash se BTC<SMA100. Diversificare su 3
|
||||
asset invece di 2 ha quasi dimezzato il DD (40%→26%) alzando il ritorno.</p>""", g_rot, t_rot)
|
||||
|
||||
c_pr = card("PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL)",
|
||||
c_pr = card("PR01 — Pairs Reversion (ETH/BTC, LTC/ETH, ADA/ETH, BTC/LTC, ETH/SOL + ETH/BTC 15m)",
|
||||
B("pairs", "PAIRS") + real, """
|
||||
<p><b>Market-neutral</b>: quando il rapporto fra due asset si allontana troppo dalla sua media
|
||||
(|z| del log-ratio ≥ 2), compra la gamba debole e shorta la forte; chiude quando il rapporto
|
||||
rientra (|z| ≤ 0.75) o dopo 72 barre. Config <b>universale</b> per tutte le coppie (niente tuning
|
||||
per-coppia = anti-overfit). Correlazione col mercato ~0.05: rende anche quando il mercato è fermo.
|
||||
Fee su 2 gambe. Senza stop per design → position size ridotto a 0.20 (esposizione ≈ validato).</p>
|
||||
<p class='sub'><b>BLEND timeframe (nuovo, 2026-06-09)</b>: ETH/BTC gira anche a <b>15m</b> accanto al 1h
|
||||
(config n=66, |z|≥1.67, exit |z|≤1.0 o 35 barre). Origine: gioco "Blind Traders" (100 agenti ciechi
|
||||
su dati anonimi); testato col gate PORT06 — <b>decorrelato dal 1h (corr 0.37)</b>, robusto (16/16),
|
||||
e l'edge regge anche filtrando le candele flat ETH 15m (<b>flat-skip</b>: niente ingresso/uscita su
|
||||
barre stale O=H=L=C). Worker validato (replay == backtest). A <b>mezza size</b> (blend-tilt prudente
|
||||
sul caveat slippage): porta il PORT06 a FULL Sharpe ~7.2 / OOS ~9.7.</p>
|
||||
<p class='sub'>Esecuzione reale a 2 gambe su Deribit testnet (<code>PairsExecutionClient</code>):
|
||||
open/close long A / short B, leg-risk unwind, mai <code>close_position</code>.</p>""", g_pr, t_pairs)
|
||||
|
||||
@@ -703,9 +720,9 @@ locale (il regime corto a 365g non era robusto: trade-rate 22% vs 10% validato).
|
||||
<title>PythagorasGoal — Strategie attive PORT06</title><style>{CSS}</style></head>
|
||||
<body><div class="wrap">
|
||||
<h1>PythagorasGoal — Strategie attive</h1>
|
||||
<p class="sub">Portafoglio live <b>PORT06</b> — definizione 17 sleeve; <b>pool live real-only 14 sleeve</b>
|
||||
<p class="sub">Portafoglio live <b>PORT06</b> — definizione {n_def} sleeve; <b>pool live real-only 15 sleeve</b>
|
||||
(i 3 book multi-asset girano in statistica, fuori dal capitale-pool). Capitale pool €2.000, leva 2x ·
|
||||
v{ver} · generato {now} · backtest canonico: FULL Sharpe 6.61 / DD 3.58% — OOS Sharpe 8.77 / DD 1.34%</p>
|
||||
v{ver} · generato {now} · backtest canonico: {hdr}</p>
|
||||
<div class="card">
|
||||
<p>Tre famiglie principali quasi <b>scorrelate</b> fra loro (fade↔honest ~0.05, pairs ~0.02-0.09,
|
||||
shape ~0.08): la diversificazione è la leva anti-drawdown. Pesi equal con tetti per famiglia,
|
||||
@@ -728,7 +745,7 @@ non si fada un crollo/parabolica), <b>EXIT-16</b> (stop solo sul close confermat
|
||||
{c_dip}
|
||||
{c_tr}
|
||||
{c_rot}
|
||||
<h2>PAIRS — spread reversion market-neutral <span class="sub">(5 coppie × 5.88%, famiglia ≤33%)</span></h2>
|
||||
<h2>PAIRS — spread reversion market-neutral <span class="sub">(6 sleeve: 5 coppie 1h + ETH/BTC 15m a mezza size, famiglia ≤33%)</span></h2>
|
||||
{c_pr}
|
||||
<h2>TSM — trend-following multi-orizzonte <span class="sub">(1 sleeve × 6.47%)</span></h2>
|
||||
{c_tsm}
|
||||
@@ -740,7 +757,7 @@ non si fada un crollo/parabolica), <b>EXIT-16</b> (stop solo sul close confermat
|
||||
<li><b>Fee sempre incluse</b>: 0.10% round-trip taker Deribit (misurate reali = assunte). Molte operazioni = morte per fee: ogni strategia regge lo stress a fee doppie.</li>
|
||||
<li><b>Niente look-ahead</b>: direzione e prezzo decisi solo con dati fino al close corrente; barre in formazione escluse (lezione EXIT-16). La famiglia squeeze (accuratezze 76-82%) è stata scartata proprio per questo artefatto.</li>
|
||||
<li><b>Gate out-of-sample</b>: nessun meccanismo va in produzione senza migliorare (o non degradare) il portafoglio FULL e OOS — robusto individualmente ≠ migliora PORT06.</li>
|
||||
<li><b>Esecuzione reale shadow (~81% del portafoglio)</b>: 14 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 5 pairs (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.</li>
|
||||
<li><b>Esecuzione reale shadow (~83% del portafoglio)</b>: 15 sleeve eseguono ordini reali su Deribit testnet accanto al sim — i 6 fade + DIP01 (single-leg, TP limit al livello, disaster-stop −30% on-book), i 6 pairs incl. <b>ETH/BTC 15m flat-skip</b> (2 gambe, leg-risk unwind) e i 2 SH01 (single-leg, exit a orizzonte, niente TP/SL). Restano simulati solo i book multi-asset TR01/ROT02/TSM01 (bloccati dal capitale: serve ~€20k per il rumore di arrotondamento). Fee reali verificate dai trade; divergenze sim/reale ≥100bps alertate su Telegram.</li>
|
||||
</ul></div>
|
||||
<p class="sub">Generato da <code>scripts/analysis/make_strategy_doc.py</code> — grafici da episodi reali sui dati parquet locali.</p>
|
||||
</div></body></html>"""
|
||||
|
||||
@@ -141,7 +141,7 @@ def pairs_sim_flat(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
|
||||
cap = peak = 1000.0; dd = 0.0; last = -1
|
||||
trades = wins = 0; rets = []; yearly = {}
|
||||
trades = wins = 0; rets = []; yearly = {}; yearly_n = {}
|
||||
eq_ts, eq_v = [], []
|
||||
n_skip_entry = 0
|
||||
kmax = max_bars + (scan_buffer if flat_skip else 0)
|
||||
@@ -176,6 +176,7 @@ def pairs_sim_flat(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 = 0.0
|
||||
if len(rets) > 1 and np.std(rets) > 0:
|
||||
@@ -183,7 +184,7 @@ def pairs_sim_flat(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,
|
||||
cagr=cagr, dd=dd * 100, sharpe=sharpe, yearly=yearly, yearly_n=yearly_n,
|
||||
eq_ts=eq_ts, eq_v=eq_v, n_skip_entry=n_skip_entry)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user