Files
Adriano Dal Pastro 14522262e6 chore(reset): v2.0.0 — storico certificato Deribit mainnet, ripartenza pulita
Reset del progetto su fondamenta verificate dopo la scoperta che l'intera
libreria "validata OOS" era artefatto di feed contaminato (print fantasma del
feed Cerbero TESTNET + storico Binance/USDT).

- Storico ricostruito da Deribit MAINNET (ccxt pubblico, tokenless) e
  CERTIFICATO (certify_feed.py): BTC/ETH puliti su TUTTA la storia
  (mediana 2-6 bps vs Coinbase USD), integrita' OHLC + coerenza resample
  (maxΔ 0.00) + cross-venue OK. Alt esclusi (illiquidi/divergenti: LTC/DOGE
  50-82% barre flat; XRP/BNB non certificabili).
- Verdetto sul feed pulito: FADE / PAIRS / XS01 / TSM01 morti (ogni
  portafoglio Sharpe -2.3..-3.0, DD ~40%); solo SH01 e frammenti HONEST
  con segnale residuo, da ri-validare in isolamento.
- Cleanup "restart pulito": strategie, stack live (src/live, src/portfolio,
  runner/executor, yml, docker), ~100 script ricerca/gate, waste/games/
  portfolios, dati non certificati + cache e 60+ diari -> archiviati in Old/
  (preservati, non cancellati). Diario consolidato in un unico documento.
- Skeleton ricerca tenuto: Strategy ABC + indicatori + src/fractal +
  src/backtest/engine + load_data; tool dati certificati (rebuild_history,
  certify_feed, audit_feed, multi_source_check).
- Universo dati ATTIVO: solo BTC/ETH (5m/15m/1h); guardrail fisico
  (load_data su alt -> FileNotFoundError). Esecuzione DISABILITATA, conto flat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:20:59 +00:00

87 lines
3.5 KiB
Python

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]
elif 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 & DVOL<p40)",g_hurst_calm),
("VRP<0 Fade (core driver)",g_vrp_neg),
("HigVRP Fade (Higuchi>1.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}%)")