research: espandere universo XS01 a 52 asset DILUISCE (negativo) -> XS01 blindato sui 19 major

Esteso fetch_hyperliquid a 52 alt certificati (cross-venue vs Binance, flat 0%, 2024+; +gate
delistato per MKR/FXS). Ma il cross-sectional momentum sui 52 e' NEGATIVO (FULL -0.1..-0.6, k grande
non aiuta) vs +0.67/OOS0.91 sui 19 major (stessa finestra): i ~33 small-cap (WIF/JUP/ORDI/PYTH/TAO..)
sono idiosincratici/mean-reverting e rovesciano il momentum relativo. "Piu' asset = piu' robusto"
e' FALSO per l'XS momentum: la breadth utile e' quella dei major liquidi.

Fix: lo sleeve _xsec_returns usa XS_UNIVERSE esplicito (19 major), non glob-all (aggiungere parquet
certificati non lo rompe piu'). I 52 parquet restano su disco per ricerca futura, non per XS01.
Portafoglio ripristinato e invariato: TP01 70% + XS01 30%, FULL Sh 1.41 / HOLD 1.15. 12 test ok.
Diario 2026-06-19-xsec-universe-expansion.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-19 21:00:00 +00:00
parent 53d0134cb1
commit 8426d05f12
3 changed files with 65 additions and 12 deletions
+14 -5
View File
@@ -54,16 +54,25 @@ import glob as _glob
from pathlib import Path as _Path
XS_CFG = dict(L=30, H=10, k=5, mode="mom", target_vol=0.20)
_HL_DIR = _Path(__file__).resolve().parents[2] / "data" / "raw"
# UNIVERSO ESPLICITO = 19 ALT LIQUIDI MAJOR. NB (2026-06-19): allargare a 52 asset (incluso
# small-cap WIF/JUP/ORDI/PYTH/TAO...) DILUISCE l'edge -> momentum cross-section NEGATIVO sui 52.
# I major sono il sweet spot. NON usare glob-all (i parquet extra certificati servono ad altra
# ricerca, non a XS01). Vedi diario 2026-06-19-xsec-universe-expansion.md.
XS_UNIVERSE = ["BTC", "ETH", "SOL", "BNB", "XRP", "DOGE", "AVAX", "LINK", "LTC", "ADA",
"ARB", "OP", "SUI", "APT", "INJ", "TIA", "SEI", "NEAR", "AAVE"]
def _xsec_returns() -> pd.Series:
cols = {}
for p in sorted(_glob.glob(str(_HL_DIR / "hl_*_1d.parquet"))):
for sym in XS_UNIVERSE:
p = _HL_DIR / f"hl_{sym.lower()}_1d.parquet"
if not p.exists():
continue
d = pd.read_parquet(p)
cols[_Path(p).stem] = pd.Series(d["close"].values.astype(float),
index=pd.to_datetime(d["timestamp"], unit="ms", utc=True))
if not cols:
raise FileNotFoundError("universo Hyperliquid assente: gira scripts/analysis/fetch_hyperliquid.py")
cols[sym] = pd.Series(d["close"].values.astype(float),
index=pd.to_datetime(d["timestamp"], unit="ms", utc=True))
if len(cols) < 10:
raise FileNotFoundError("universo Hyperliquid XS01 incompleto: gira scripts/analysis/fetch_hyperliquid.py")
C = pd.concat(cols, axis=1, join="inner").sort_index().dropna()
px = C.values; n, A = px.shape
L, H, k, mode, tv = XS_CFG["L"], XS_CFG["H"], XS_CFG["k"], XS_CFG["mode"], XS_CFG["target_vol"]