1"""chronos-x CLI: forecast from a saved model and a cached grid (private data stays local)."""2from __future__ import annotations34import argparse5import json6from pathlib import Path78import numpy as np910from ..data.windows import SymbolGrid, WindowConfig, make_example11from ..train.sampling import collate12from .serialization import load_model131415def main() -> None:16 ap = argparse.ArgumentParser(description="CHRONOS-X forecast at one origin")17 ap.add_argument("model"); ap.add_argument("grid_dir"); ap.add_argument("--session", type=int, required=True)18 ap.add_argument("--slot", type=int, required=True); ap.add_argument("--horizons", default="5,15,30,60")19 a = ap.parse_args()20 import torch21 m = load_model(Path(a.model)); m.eval()22 g = SymbolGrid.load(Path(a.grid_dir))23 ex = make_example(g, a.session, a.slot, WindowConfig()); ex["sym"] = np.int64(0)24 b = collate([ex])25 with torch.no_grad():26 o = m(b)27 out = {"symbol": g.symbol, "session_date": g.meta["session_dates"][a.session], "slot": a.slot, "sigma": float(ex["sigma"])}28 for H in (int(h) for h in a.horizons.split(",")):29 var = float((o["scale"][0, :H] ** 2 * (o["nu"][0, :H] / (o["nu"][0, :H] - 2))).sum())30 out[f"H{H}"] = {"mu_cum": float(o["mu"][0, :H].sum()), "sd_cum_indep": var ** 0.5}31 print(json.dumps(out, indent=1))323334if __name__ == "__main__":35 main()36