import sys; sys.path.insert(0,".") import numpy as np, pandas as pd from scripts.analysis.regime_lab import load_features from scripts.analysis.explore_lab import atr FEE=0.001; LEV=3 def build(df, gate, k=2.5, sl_atr=2.0, mb=24, bb=50): c=df['close'].values; a=atr(df,14) ma=pd.Series(c).rolling(bb).mean().values; sd=pd.Series(c).rolling(bb).std().values ent=[] for i in range(bb+14,len(c)-1): if np.isnan(sd[i]) or sd[i]==0 or np.isnan(a[i]): continue if not gate(df,i): continue if c[i]ma[i]+k*sd[i]: d,sl=-1,c[i]+sl_atr*a[i] else: continue ent.append({'i':i,'d':d,'tp':ma[i],'sl':sl,'mb':mb}) return ent def per_year(df, ent): """replay intrabar fedele (sl-first, tp, poi max_bars@close) -> per anno {n,ret%,win%}.""" h=df['high'].values; l=df['low'].values; c=df['close'].values ts=pd.to_datetime(df['timestamp'],unit='ms',utc=True) Y={} last=-1 for e in ent: i=e['i'] if i<=last: continue d=e['d']; tp=e['tp']; sl=e['sl']; j=min(i+e['mb'],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 last=j; yr=ts.iloc[i].year if yr not in Y: Y[yr]=[0,0.0,0] Y[yr][0]+=1; Y[yr][1]+=ret*100; Y[yr][2]+= (ret>0) return Y # gate functions def g_hurst_calm(df,i): return df['hurst'].iloc[i]<0.55 and not np.isnan(df['dvol_pct'].iloc[i]) and df['dvol_pct'].iloc[i]<0.40 def g_vrp_neg(df,i): return not np.isnan(df['vrp'].iloc[i]) and df['vrp'].iloc[i]<0 def g_hig_vrp(df,i): hi=df['higuchi'].iloc[i]; return (not np.isnan(hi)) and hi>1.5 and (not np.isnan(df['vrp'].iloc[i])) and df['vrp'].iloc[i]<0 def g_none(df,i): return True STRATS=[("HurstCalmFade (hurst<.55 & DVOL1.5 & VRP<0)",g_hig_vrp), ("Fade NUDA (no gate, baseline)",g_none)] # regime mercato BTC per anno (da BTC close annuale) btc=load_features("BTC","1d") bts=pd.to_datetime(btc['timestamp'],unit='ms',utc=True); bc=btc['close'].values mkt={} for yr in range(2021,2027): m=(bts.dt.year==yr).values if m.sum()>5: r=(bc[m][-1]/bc[m][0]-1)*100 mkt[yr]=("BULL" if r>40 else "BEAR" if r<-30 else "RANGE", r) for asset in ("BTC","ETH"): df=load_features(asset,"1h") print(f"\n{'='*78}\n {asset} 1h — performance per anno (somma ret% per-trade, netto leva3x+fee0.10%)\n{'='*78}") print(f" {'Strategia':<40} " + " ".join(f"{y}" for y in range(2021,2027))) for name,g in STRATS: ent=build(df,g); Y=per_year(df,ent) cells=[] for y in range(2021,2027): if y in Y and Y[y][0]>0: cells.append(f"{Y[y][1]:+5.0f}") else: cells.append(" . ") print(f" {name:<40} " + " ".join(cells)) # riga trades/anno per la strategia principale ent=build(df,g_hurst_calm); Y=per_year(df,ent) tr=" ".join(f"{Y.get(y,[0])[0]:>5}" for y in range(2021,2027)) print(f" {'(HurstCalmFade trades/anno)':<40} {tr}") print(f"\n REGIME MERCATO BTC per anno (ret% annuale prezzo):") for y in range(2021,2027): if y in mkt: print(f" {y}: {mkt[y][0]:6} ({mkt[y][1]:+.0f}%)")