From 8fd8f64368db46a54738bf0bc7e2aeb2c82d3d54 Mon Sep 17 00:00:00 2001 From: Adriano Dal Pastro Date: Tue, 2 Jun 2026 11:48:02 +0000 Subject: [PATCH] test(research): FR01 NON migliora PORT06 (verdetto decisivo) Contributo marginale al MASTER (equal-weight): OOS Sharpe 8.89->8.72 (diluisce), OOS ret +175%->+156%. Corr FR01 vs MASTER +0.18/+0.23. Sharpe daily-return standalone ~1.85 (non il 3.73 per-trade) -> troppo basso per un PORT06 a 8.89. Ridondanza robusta. ESITO: search a 100 agenti rigoroso, ma nessuna strategia migliora PORT06. Deploy abbandonato, resta record di ricerca sul branch. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/diary/2026-06-02-fractal-argo-search.md | 28 +++++++--- scripts/analysis/fractal_argo_master_corr.py | 54 ++++++++++++++++++++ 2 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 scripts/analysis/fractal_argo_master_corr.py diff --git a/docs/diary/2026-06-02-fractal-argo-search.md b/docs/diary/2026-06-02-fractal-argo-search.md index 8e6d917..8edf22d 100644 --- a/docs/diary/2026-06-02-fractal-argo-search.md +++ b/docs/diary/2026-06-02-fractal-argo-search.md @@ -66,10 +66,24 @@ condizionata dal regime (VRP<0 / hurst-low / dvol-low)**, non un motore ortogona **riduzione DD aggregato come sleeve a bassa esposizione**. La correlazione bassa lo qualifica come diversificatore reale. -## Resta da fare prima del deploy (NON ancora superato) -1. Verifica di correlazione formale sull'**intero MASTER** (`combine_v2.py`), non solo vs le 3 - fade BTC — confermare che migliora Sharpe/DD OOS del PORT06. -2. **Wiring DVOL live**: il gate dipende da dvol_pct; il backtest usa la cache `regime_lab`, ma il - runner live non ha un feed DVOL. Va costruito (regime_fetcher in produzione + allineamento - causale) prima di tradare FR01 live. -3. Walk-forward per-finestra + replay worker == backtest + exit intrabar via StrategyWorker. +## TEST DECISIVO SUL MASTER — VERDETTO FINALE: NON deployare + +Misurato il contributo marginale di FR01 al PORT06 intero (equal-weight, `master_corr`): + +| Portafoglio | FULL Sharpe | OOS Sharpe | OOS DD | OOS ret | +|-------------|:--:|:--:|:--:|:--:| +| PORT06 (17 sleeve) | 6,62 | **8,89** | 1,2% | +175% | +| PORT06 + FR01 (19) | 6,55 | **8,72** | 1,1% | +156% | + +**FR01 NON migliora il PORT06: lo DILUISCE** (OOS Sharpe 8,89→8,72, OOS ret +175%→+156%; DD +marginalmente meglio 1,2→1,1% ma a costo di Sharpe). Corr FR01 vs MASTER +0,18 (BTC)/+0,23 (ETH). + +**Causa + nota di onestà metrica:** lo Sharpe "3,73" dei report del workflow è **per-trade/annuale** +(`explore_lab`); quello rilevante per il portafoglio è lo **Sharpe daily-return** (`combine`), che per +FR01 è solo **~1,85/1,53** — troppo basso per muovere un PORT06 a 8,89. È "ridondanza robusta": +mean-reversion regime-gated che si sovrappone a ciò che il MASTER già fa. + +**ESITO: il search a 100 agenti ha trovato strategie robuste e causali, ma NESSUNA migliora il +PORT06.** Non deployare FR01 né i candidati gemelli. Valore del progetto resta nell'estendere +fade/pairs validati. Tutto resta come RECORD DI RICERCA sul branch (non si merge in produzione). +Wiring DVOL live e walk-forward: non necessari, deploy abbandonato. diff --git a/scripts/analysis/fractal_argo_master_corr.py b/scripts/analysis/fractal_argo_master_corr.py new file mode 100644 index 0000000..1d16395 --- /dev/null +++ b/scripts/analysis/fractal_argo_master_corr.py @@ -0,0 +1,54 @@ +import sys; sys.path.insert(0,".") +import numpy as np, pandas as pd +from scripts.analysis.combine_portfolio import IDX, SPLIT, INIT, _norm, metrics, port_returns +from src.portfolio.sleeves import all_sleeve_equities +from scripts.analysis.regime_lab import load_features +from scripts.analysis.explore_lab import atr +FEE=0.001; LEV=3; POS=0.15 + +def fr01_daily_equity(asset): + df=load_features(asset,"1h") + c=df['close'].values; h=df['high'].values; l=df['low'].values; a=atr(df,14) + ma=pd.Series(c).rolling(50).mean().values; sd=pd.Series(c).rolling(50).std().values + ts=pd.to_datetime(df['timestamp'],unit='ms',utc=True) + eq=np.full(len(c),INIT,float); cap=INIT; last=-1 + for i in range(64,len(c)-1): + if i<=last or np.isnan(sd[i]) or sd[i]==0 or np.isnan(a[i]): continue + if df['hurst'].iloc[i]>=0.55: continue + if np.isnan(df['dvol_pct'].iloc[i]) or df['dvol_pct'].iloc[i]>=0.40: continue + if c[i]ma[i]+2.5*sd[i]: d,sl,tp=-1,c[i]+2*a[i],ma[i] + else: continue + j=min(i+24,len(c)-1); exit_p=c[j] + for t in range(i+1,j+1): + if d==1: + if l[t]<=sl: exit_p=sl; j=t; break + if h[t]>=tp: exit_p=tp; j=t; break + else: + if h[t]>=sl: exit_p=sl; j=t; break + if l[t]<=tp: exit_p=tp; j=t; break + ret=(exit_p-c[i])/c[i]*d*LEV - FEE*LEV + cap=max(cap+cap*POS*ret,10.0); eq[j:]=cap; last=j + s=pd.Series(eq,index=ts).resample("1D").last().reindex(IDX).ffill().bfill() + return _norm(s) + +members=all_sleeve_equities() +print(f"PORT06 sleeve: {len(members)} | finestra {IDX[0].date()}..{IDX[-1].date()} | OOS da idx {SPLIT} ({IDX[SPLIT].date()})") +fr={"FR01_BTC":fr01_daily_equity("BTC"), "FR01_ETH":fr01_daily_equity("ETH")} + +base=port_returns(members) # equal-weight 17 sleeve (metro combine) +aug =port_returns({**members,**fr}) # + FR01x2 (19 sleeve) + +def show(tag, dr): + f=metrics(dr); o=metrics(dr,lo=SPLIT) + print(f" {tag:<22} FULL: Sharpe {f['sharpe']:.2f} DD {f['dd']:.1f}% ret {f['ret']:+.0f}% | OOS: Sharpe {o['sharpe']:.2f} DD {o['dd']:.1f}% ret {o['ret']:+.0f}%") + +print("\n=== MASTER equal-weight: con/senza FR01 ===") +show("PORT06 (17 sleeve)", base) +show("PORT06 + FR01 (19)", aug) + +# correlazione FR01 vs portafoglio MASTER aggregato + standalone +for k,e in fr.items(): + r=e.pct_change().fillna(0.0); corr=np.corrcoef(r, base)[0,1] + f=metrics(r); o=metrics(r,lo=SPLIT) + print(f"\n {k}: corr vs MASTER = {corr:+.3f} | standalone OOS Sharpe {o['sharpe']:.2f} DD {o['dd']:.1f}% ret {o['ret']:+.0f}%")