"""XV01 — Low Realized-Volatility Anomaly MECHANISM: Score = -roll_std(ret, W) (long low-vol / short high-vol alts). The low-vol anomaly: lower-volatility assets tend to outperform on a risk-adjusted basis. Grid: W in {20, 30, 60}; universe in {all, majors}; long-short AND long-only. Goal: find a DISTINCT signal from XS01 (plain momentum) that ADDS to the live portfolio. """ import sys sys.path.insert(0, "/opt/docker/PythagorasGoal/scripts/research/xsec") import xslib as xs import numpy as np print("XV01 — Low Realized-Volatility Anomaly") print("=" * 60) # --- 5 targeted backtests --- # 1) Full universe, W=20 (short-term vol), LS — baseline low-vol on all alts rep1 = xs.study_xs( "XV01_ALL_W20_LS", lambda P: -xs.roll_std(P.ret, 20), universe="all", H=10, k=5, long_short=True ) print(xs.fmt(rep1)) print("JSON:", xs.as_json(rep1)) print() # 2) Full universe, W=30, LS — medium-window vol (the main hypothesis) rep2 = xs.study_xs( "XV01_ALL_W30_LS", lambda P: -xs.roll_std(P.ret, 30), universe="all", H=10, k=5, long_short=True ) print(xs.fmt(rep2)) print("JSON:", xs.as_json(rep2)) print() # 3) Full universe, W=60, LS — longer-window vol rep3 = xs.study_xs( "XV01_ALL_W60_LS", lambda P: -xs.roll_std(P.ret, 60), universe="all", H=10, k=5, long_short=True ) print(xs.fmt(rep3)) print("JSON:", xs.as_json(rep3)) print() # 4) Majors only (19), W=30, LS — smaller universe, less noise rep4 = xs.study_xs( "XV01_MAJORS_W30_LS", lambda P: -xs.roll_std(P.ret, 30), universe="majors", H=10, k=5, long_short=True ) print(xs.fmt(rep4)) print("JSON:", xs.as_json(rep4)) print() # 5) Full universe, W=30, long-only top-k (lowest vol, long only) # The "defensive" alt selection: pick alts with lowest realized vol rep5 = xs.study_xs( "XV01_ALL_W30_LO", lambda P: -xs.roll_std(P.ret, 30), universe="all", H=10, k=5, long_short=False ) print(xs.fmt(rep5)) print("JSON:", xs.as_json(rep5)) print() # Pick best: prefer earns_slot, then hold-out sharpe, then full sharpe, then distinctness from XS01 all_reps = [rep1, rep2, rep3, rep4, rep5] def score_rep(r): earns = int(r["earns_slot"]) hold_sh = r["holdout"].get("sharpe", -9) full_sh = r["full"]["sharpe"] corr_xs01 = r["corr_xs01"] if r["corr_xs01"] is not None else 1.0 distinctness = 1 - abs(corr_xs01) # higher = more distinct return (earns, hold_sh, full_sh, distinctness) best = max(all_reps, key=score_rep) print("=" * 60) print(f"BEST CONFIG: {best['name']}") print(xs.fmt(best)) print("JSON:", xs.as_json(best))