1"""H5 (exploratory): cost-aware signal evaluation from saved predictions (runs where pred_*.npz live).2Median of the cumulative return = sum of per-minute Student-t locations (symmetric marginals)."""3from __future__ import annotations45import argparse6import json7import sys8from pathlib import Path910import numpy as np11import pandas as pd1213ROOT = Path(__file__).resolve().parents[1]14sys.path.insert(0, str(ROOT / "src"))15from chronos_x.eval.economic import signal_pnl # noqa: E402161718def main() -> None:19 ap = argparse.ArgumentParser(); ap.add_argument("--exp", default="main"); ap.add_argument("--tag", default="test")20 ap.add_argument("--models", default="mrpt_small,mrpt_base,mlp,tcn"); ap.add_argument("--horizons", default="5,15,30,60")21 a = ap.parse_args()22 d = ROOT / "results" / "metrics" / a.exp23 tab = pd.read_csv(d / f"origins_{a.tag}.csv")24 out = []25 for m in a.models.split(","):26 f = d / f"pred_{m}_{a.tag}.npz"27 if not f.exists():28 continue29 p = np.load(f)30 mu = p["mu"]; ym = p["y_mask"]31 for H in (int(h) for h in a.horizons.split(",")):32 med = (mu[:, :H] * ym[:, :H]).sum(1)33 real = tab[f"cum_{H}"].values34 assert np.allclose((p["y"][:, :H] * ym[:, :H]).sum(1), real, atol=1e-6)35 for cost in (0.0, 1.0, 2.5, 5.0, 10.0):36 for k in (1.0, 2.0):37 r = signal_pnl(med, real, tab, cost_bps=cost, k=k)38 out.append({"model": m, "H": H, **r})39 # information content without trading: correlation and regression slope of realised on median40 sl = np.polyfit(med, real, 1)[0] if med.std() > 0 else np.nan41 out.append({"model": m, "H": H, "cost_bps": -1, "k": 0, "corr": float(np.corrcoef(med, real)[0, 1]), "slope": float(sl), "n": int(len(med)),42 "median_abs_bps": float(np.abs(med).mean() * 1e4)})43 df = pd.DataFrame(out); df.to_csv(d / f"economic_{a.tag}.csv", index=False)44 print(df.to_string(index=False, float_format=lambda x: f"{x:.4g}"))454647if __name__ == "__main__":48 main()49