"""Test del filone B — INTRADAY REGIME (scripts/research/intraday_regime.py). Verifica leggera e veloce (un solo asset) che: * i target factory producano array della lunghezza giusta e CAUSALI (no look-ahead); * il meccanismo ERM (efficiency-ratio regime momentum) sia long/short di natura; * la cella canonica ERM 8h L=2 thr=0.35 abbia Sharpe FULL positivo netto fee (sanity dell'edge). NB: NON costruisce la baseline TP01/SKH01 (lento) — quello e' nello script di ricerca. """ import sys import importlib.util import numpy as np sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/alt") import altlib as al # noqa: E402 _spec = importlib.util.spec_from_file_location( "intraday_regime", "/opt/docker/PythagorasGoal/scripts/research/intraday_regime.py") ir = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(ir) def test_erm_target_shape_and_ls(): df = al.get("BTC", "8h") tgt = ir.make_erm(tf="8h", L_days=2.0, thr=0.35, long_flat=False)(df) assert len(tgt) == len(df) assert np.isfinite(tgt).all() # L/S: deve esistere sia esposizione long sia short (non e' long-only) assert (tgt > 0).any() and (tgt < 0).any() # long_flat=True -> nessuno short tgt_lf = ir.make_erm(tf="8h", L_days=2.0, thr=0.35, long_flat=True)(df) assert (tgt_lf >= -1e-9).all() def test_erm_causal_no_leak(): # causality_ok ricalcola il target su prefissi troncati e pretende che la coda combaci res = al.causality_ok(ir.make_erm(tf="8h", L_days=2.0, thr=0.35, long_flat=False), tf="8h", assets=("BTC",)) assert res["ok"], f"look-ahead in ERM: {res}" def test_erm_winner_positive_full_sharpe(): fn = ir.make_erm(tf="8h", L_days=2.0, thr=0.35, long_flat=False) for a in ("BTC", "ETH"): df = al.get(a, "8h") ev = al.eval_weights(df, fn(df), fee_side=0.0005) # 0.10% RT assert ev["full"]["sharpe"] > 0.5, f"{a} full Sharpe {ev['full']['sharpe']}" def test_vbr_and_tod_causal(): for fn in (ir.make_vbr(tf="8h", k=1.0, atr_win=14, long_flat=False), ir.make_tod(tf="1h", long_flat=True)): res = al.causality_ok(fn, tf=("8h" if fn is not None else "1h"), assets=("BTC",)) if False else None # VBR causale (8h) e TOD causale (1h), un asset per velocita' assert al.causality_ok(ir.make_vbr(tf="8h", k=1.0, atr_win=14, long_flat=False), tf="8h", assets=("BTC",))["ok"] assert al.causality_ok(ir.make_tod(tf="1h", long_flat=True), tf="1h", assets=("BTC",))["ok"]