SPB Git

spb/wp46_uqo

Public
3.0 KB · 63 lines python
1#!/usr/bin/env python32"""Expand the frozen configs into a job list (instrument x model x distribution x estimation variant).3usage: make_jobs.py --name main [--tier A,B] [--symbols ...] [--oos-start 2012-01-03] [--oos-end 2026-10-30]4       [--window 1000] [--refit 5] [--expanding] [--models m1,m2]"""5from __future__ import annotations67import argparse8import json9import sys10from pathlib import Path1112import yaml1314ROOT = Path(__file__).resolve().parents[1]15sys.path.insert(0, str(ROOT / "src"))161718def main() -> None:19    ap = argparse.ArgumentParser()20    ap.add_argument("--name", required=True)21    ap.add_argument("--tier", default="A,B")22    ap.add_argument("--symbols", default="")23    ap.add_argument("--models", default="")24    ap.add_argument("--oos-start", default=None)25    ap.add_argument("--oos-end", default=None)26    ap.add_argument("--window", type=int, default=None)27    ap.add_argument("--refit", type=int, default=None)28    ap.add_argument("--expanding", action="store_true")29    ap.add_argument("--status", default="implemented", help="comma-separated registry statuses to include (implemented,extension)")30    a = ap.parse_args()31    reg = yaml.safe_load(open(ROOT / "configs" / "model_registry.yaml"))["models"]32    inst = yaml.safe_load(open(ROOT / "configs" / "instruments.yaml"))33    prot = yaml.safe_load(open(ROOT / "configs" / "forecast_protocol.yaml"))34    uni = inst.get("universe") or inst["candidates"]35    syms = [s for cls in uni for s in uni[cls]]36    if a.symbols:37        syms = [s for s in a.symbols.split(",") if s]38    tiers = a.tier.split(",")39    oos_start = a.oos_start or prot["periods"]["validation"]["start"]40    oos_end = a.oos_end or prot["periods"]["test"]["end"]41    window = a.window or prot["estimation"]["window"]42    refit = a.refit or prot["estimation"]["refit_every"]43    want = set(a.models.split(",")) if a.models else None44    jobs = []45    for s in syms:46        for mid, m in reg.items():47            if m["status"] not in a.status.split(",") or m["tier"] not in tiers or (want and mid not in want):48                continue49            for dist in m["dists"]:50                jobs.append(dict(symbol=s, model_id=mid, dist=dist, tier=m["tier"], window=window, refit_every=refit,51                                 expanding=a.expanding, rm_proxy=prot["tier_b_input"], oos_start=oos_start, oos_end=oos_end,52                                 seed=prot["estimation"]["seed"], max_restarts=prot["estimation"]["max_restarts"]))53    # heavy jobs first (better load balance): msgarch, figarch, realgarch, aparch/egarch (simulation forecasts)54    rank = {"msgarch2": 0, "figarch11": 1, "realgarch11": 2, "aparch11": 3, "egarch11": 4, "tarch11": 5, "avgarch11": 6}55    jobs.sort(key=lambda j: (rank.get(j["model_id"], 9), j["symbol"]))56    out = ROOT / "results" / "manifests" / f"jobs_{a.name}.json"57    out.write_text(json.dumps(jobs, indent=0))58    print(out, len(jobs), "jobs;", len(syms), "symbols;", sorted({j['model_id'] for j in jobs}))596061if __name__ == "__main__":62    main()63
Files · main
Menu

Theme