14522262e6
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>
57 lines
2.9 KiB
Python
57 lines
2.9 KiB
Python
import sys; sys.path.insert(0,".")
|
|
import numpy as np, pandas as pd, importlib
|
|
from scripts.analysis.combine_portfolio import IDX, SPLIT, INIT, _norm, metrics, port_returns, build_trades
|
|
from src.portfolio.sleeves import all_sleeve_equities
|
|
from scripts.analysis.regime_lab import load_features
|
|
|
|
def load_strat(mod):
|
|
m=importlib.import_module(mod)
|
|
return next(v() for k,v in vars(m).items() if isinstance(v,type) and hasattr(v,'generate_signals') and getattr(v,'__module__','')==m.__name__)
|
|
FADES={"MR01":("scripts.strategies.MR01_bollinger_fade",dict(bb_window=50,k=2.5,sl_atr=2.0,max_bars=24,trend_max=3.0)),
|
|
"MR02":("scripts.strategies.MR02_donchian_fade",dict(n=20,sl_atr=2.0,max_bars=24,trend_max=3.0)),
|
|
"MR07":("scripts.strategies.MR07_return_reversal",dict(n=50,k=3.5,tp_atr=2.0,sl_atr=1.5,max_bars=24,trend_max=3.0))}
|
|
FEE=0.001; LEV=3; POS=0.15
|
|
|
|
def fade_equity_filtered(code, asset, hurst_thr=None):
|
|
"""equity giornaliera dello sleeve fade, opz. filtrata Hurst<thr (skip hurst>=thr). Convenzione fade_daily_equity."""
|
|
mod,par=FADES[code]; s=load_strat(mod)
|
|
df=load_features(asset,"1h"); ts=pd.to_datetime(df['timestamp'],unit='ms',utc=True)
|
|
h=df['high'].values; l=df['low'].values; c=df['close'].values; hur=df['hurst'].values
|
|
eq=np.full(len(c),INIT,float); cap=INIT; last=-1
|
|
for sg in s.generate_signals(df,ts,**par):
|
|
i=sg.idx
|
|
if i<=last: continue
|
|
if hurst_thr is not None and not np.isnan(hur[i]) and hur[i]>=hurst_thr: continue # FILTRO
|
|
d=sg.direction; tp=sg.metadata['tp']; sl=sg.metadata['sl']; mb=sg.metadata['max_bars']
|
|
j=min(i+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
|
|
cap=max(cap+cap*POS*ret,10.0); eq[j:]=cap; last=j
|
|
sser=pd.Series(eq,index=ts).resample("1D").last().reindex(IDX).ffill().bfill()
|
|
return _norm(sser)
|
|
|
|
base=all_sleeve_equities()
|
|
fade_ids=["MR01_BTC","MR02_BTC","MR07_BTC","MR01_ETH","MR02_ETH","MR07_ETH"]
|
|
|
|
def port(members):
|
|
dr=port_returns(members); return metrics(dr), metrics(dr,lo=SPLIT)
|
|
|
|
# baseline PORT06
|
|
fB,oB=port(base)
|
|
print(f"PORT06 baseline (17 sleeve): FULL Sharpe {fB['sharpe']:.2f} DD {fB['dd']:.2f}% | OOS Sharpe {oB['sharpe']:.2f} DD {oB['dd']:.2f}% ret {oB['ret']:+.0f}%")
|
|
|
|
# sostituisci le 6 fade con versione Hurst-skip
|
|
for thr in (0.55, 0.50):
|
|
filt=dict(base)
|
|
for fid in fade_ids:
|
|
code,asset=fid.split("_")
|
|
filt[fid]=fade_equity_filtered(code,asset,hurst_thr=thr)
|
|
fF,oF=port(filt)
|
|
print(f"PORT06 + Hurst-skip h<{thr} sulle fade: FULL Sharpe {fF['sharpe']:.2f} DD {fF['dd']:.2f}% | OOS Sharpe {oF['sharpe']:.2f} DD {oF['dd']:.2f}% ret {oF['ret']:+.0f}%")
|