1import numpy as np2import pandas as pd34from wp46.estimation import JobSpec, run_job567def synthetic_panel(T=1400, seed=0):8 rng = np.random.default_rng(seed)9 s = np.empty(T); r = np.empty(T); s[0] = 1.010 for t in range(T):11 if t > 0:12 s[t] = 0.05 + 0.08 * r[t - 1] ** 2 + 0.9 * s[t - 1]13 r[t] = np.sqrt(s[t]) * rng.standard_normal()14 rv = s * rng.lognormal(0, 0.3, T)15 dates = pd.bdate_range("2010-01-04", periods=T)16 return pd.DataFrame({"session": dates, "r": r, "r_on": np.zeros(T), "rv_5m_ss": rv, "rv_5m": rv, "rv_1m": rv, "bv_5m": rv,17 "medrv_5m": rv, "valid_rm": True, "close": 100.0, "open": 100.0, "r_oc": r, "expected_bars": 391})181920def test_driver_refit_cadence_and_outputs():21 p = synthetic_panel()22 F, G = run_job(p, JobSpec("SYN", "garch11", "normal", "A", window=1000, refit_every=5, oos_start="2013-01-01", oos_end="2016-12-31"))23 assert (F.status == "ok").all()24 assert len(G) == int(np.ceil(len(F) / 5))25 assert np.all(F.h5 > F.h1) and np.all(F.h22 > F.h5)26 # origins strictly after the first `window` observations27 assert F.origin.min() > p.session.iloc[999]282930def test_driver_tier_b_and_failure_flags():31 p = synthetic_panel()32 F, G = run_job(p, JobSpec("SYN", "har_rv", "empirical", "B", window=1000, oos_start="2013-01-01", oos_end="2014-12-31"))33 assert (F.status == "ok").all() and np.isfinite(F.h1).all()34 # a missing return inside the window is reported as missing_input, never silently filled35 p2 = p.copy(); p2.loc[1100, "r"] = np.nan36 F2, _ = run_job(p2, JobSpec("SYN", "garch11", "normal", "A", window=1000, oos_start="2013-01-01", oos_end="2014-12-31"))37 affected = (F2.origin >= p.session.iloc[1100]) & (F2.origin <= p.session.iloc[min(2099, len(p) - 1)])38 assert (F2.status == "missing_input").sum() == int(affected.sum()) and affected.sum() > 0394041def test_no_leakage_whole_job():42 """Perturbing returns and realized measures after the last origin leaves every forecast of the job unchanged."""43 p = synthetic_panel()44 spec = JobSpec("SYN", "gjr11", "t", "A", window=1000, oos_start="2014-01-01", oos_end="2014-06-30")45 F1, _ = run_job(p, spec)46 p2 = p.copy(); m = p2["session"] > F1["origin"].max(); p2.loc[m, "r"] *= 4.0; p2.loc[m, "rv_5m_ss"] *= 9.047 F2, _ = run_job(p2, spec)48 assert np.array_equal(F1["h22"].values, F2["h22"].values)49 specb = JobSpec("SYN", "heavy11", "normal", "B", window=1000, oos_start="2014-01-01", oos_end="2014-06-30")50 G1, _ = run_job(p, specb); G2, _ = run_job(p2, specb)51 assert np.array_equal(G1["h5"].values, G2["h5"].values)52