"""Test del filone XS-v3: varianti STRUTTURALI di momentum cross-sectional (scripts/research/xsec_v3_momstruct). Verifica i GATE strutturali, non i numeri esatti (storia corta, ricerca): gli engine sono CAUSALI (prefix-consistency, zero look-ahead, anche quello volatility-managed custom) e una cella della griglia ESEGUE producendo una serie finita non degenere. """ from __future__ import annotations import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(PROJECT_ROOT)) import numpy as np from src.portfolio.sleeves import XS_UNIVERSE import importlib.util _spec = importlib.util.spec_from_file_location( "xsec_v3_momstruct", PROJECT_ROOT / "scripts" / "research" / "xsec_v3_momstruct.py") v3 = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(v3) xv = v3.xv def _majors(): return xv.load_matrix(XS_UNIVERSE) def test_std_engine_variants_are_causal(): """RAMOM/ACCEL/FIP usano xs_engine: ricostruiti su un prefisso, la coda combacia bit-a-bit con la run completa (gate #2 della metodologia).""" PX, VOL = _majors() vdefs = v3.variants() for name, cfg in (("RAMOM", dict(L=30, H=10, k=5)), ("ACCEL", dict(Ls=30, Ll=60, H=5, k=8)), ("FIP", dict(L=60, H=10, k=5))): res = xv.causality_prefix_check(PX, VOL, vdefs[name]["builder"], cfg) assert res["ok"], f"{name} look-ahead: max_tail_diff={res['max_tail_diff']}" assert res["max_tail_diff"] == 0.0 def test_volscaled_engine_is_causal(): """L'engine volatility-managed custom (vol-target sulla vol di MERCATO, shift 1) e' causale.""" PX, VOL = _majors() v = v3.variants()["VOLSC"] res = v3.caus_check_mktvol(PX, VOL, v["builder"], dict(L=60, H=5, k=8), B_mkt=v["B_mkt"]) assert res["ok"], f"VOLSC look-ahead: max_tail_diff={res['max_tail_diff']}" assert res["max_tail_diff"] == 0.0 def test_grid_cell_executes_finite(): """Una cella di ogni variante esegue e produce una serie GIORNALIERA finita e non degenere.""" PX, VOL = _majors() vdefs = v3.variants() for name, cfg in (("RAMOM", dict(L=60, H=10, k=5)), ("ACCEL", dict(Ls=30, Ll=90, H=5, k=8)), ("FIP", dict(L=90, H=10, k=8)), ("VOLSC", dict(L=60, H=5, k=8))): daily, turn = v3.run_variant_cfg(PX, VOL, vdefs[name], cfg) assert len(daily) > 60 assert np.isfinite(daily.values).all() assert daily.std() > 0 assert turn > 0