"""Lock del forward-monitor STATARB-RESID (scripts/live/paper_statarb.py): * config CONGELATA (W=45, sgn=+1) — non deve cambiare silenziosamente; * advance() processa SOLO le barre forward ed è IDEMPOTENTE alla punta; * a 1d il libro REAL-$600 traccia il MODELED (haircut di fill piccolo). Il segnale è quello esatto dello sweep (orthogonal_signals) → niente reimplementazione. """ import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "scripts" / "live")) import paper_statarb as ps # noqa: E402 def _fresh_state(j, back): ts, _, pos, _ = ps._signal(j) start = int(ts[-back - 1]) return dict(start_ts=start, last_ts=start, n_bars=0, pos_modeled=float(pos[-back - 1]), pos_real=float(pos[-back - 1]), cap_modeled=ps.MODELED_CAPITAL, cap_real=ps.REAL_CAPITAL, peak_modeled=ps.MODELED_CAPITAL, peak_real=ps.REAL_CAPITAL, dd_modeled=0.0, dd_real=0.0, n_trades=0) def _redirect(tmp_path, monkeypatch): monkeypatch.setattr(ps, "STATE_DIR", tmp_path) monkeypatch.setattr(ps, "STATE_FILE", tmp_path / "state.json") monkeypatch.setattr(ps, "RETURNS_FILE", tmp_path / "returns.jsonl") monkeypatch.setattr(ps, "TRADES_FILE", tmp_path / "trades.jsonl") def test_frozen_config(): """La cella vincente in-sample è W=45 sgn=+1 (relative-momentum, non mean-reversion).""" assert ps.W_FROZEN == 45 assert ps.SGN_FROZEN == +1 def test_advance_processes_forward_then_idempotent(tmp_path, monkeypatch): _redirect(tmp_path, monkeypatch) j = ps.build_joint("1d") ts, *_ = ps._signal(j) st = _fresh_state(j, back=60) st = ps.advance(st, j) assert st["n_bars"] == 60 # ha processato le 60 barre forward assert st["last_ts"] == int(ts[-1]) assert st["cap_modeled"] != ps.MODELED_CAPITAL # l'equity si è mossa # idempotente: ri-avanzare alla punta non aggiunge barre né muove l'equity eq_before = st["cap_modeled"] st2 = ps.advance(dict(st), j) assert st2["n_bars"] == 60 assert st2["cap_modeled"] == eq_before def test_real600_tracks_modeled_low_turnover(tmp_path, monkeypatch): _redirect(tmp_path, monkeypatch) j = ps.build_joint("1d") st = ps.advance(_fresh_state(j, back=250), j) rm = st["cap_modeled"] / ps.MODELED_CAPITAL - 1 rr = st["cap_real"] / ps.REAL_CAPITAL - 1 assert abs(rm - rr) < 0.05 # haircut di fill piccolo a 1d ($600)