SPB Git

spb/wp27_uqo

Public
2.9 KB · 60 lines python
1"""Phase 6 (scaling arm) — build the frozen decision library from recorded live LLM decisions and replay it2at N = 1,000 traders with zero API calls. The library policy is a k-NN replay of recorded decisions (non-adaptive);3runs are labelled provider = 'library' and reported separately from online runs."""4from __future__ import annotations56import sys7from pathlib import Path89import numpy as np10import pandas as pd1112ROOT = Path(__file__).resolve().parents[1]13sys.path.insert(0, str(ROOT / "src"))14from market_agents.experiments.config import RunConfig  # noqa: E40215from market_agents.experiments.runner import run_config  # noqa: E40216from market_agents.llm.library import DecisionLibrary, FEATURES  # noqa: E40217from market_agents.metrics.outcomes import run_outcomes  # noqa: E4021819SRC = ROOT / "results/runs/confirmatory_openai"20LIB = ROOT / "results/library/gpt-5.4-nano_single.npz"21OUT = ROOT / "results/runs/library_scale"222324def build() -> DecisionLibrary:25    run_dirs = [p.parent for p in SRC.glob("dose_*/seed*/llm_decisions.parquet")]26    if not run_dirs:27        raise SystemExit("no confirmatory runs with LLM decisions yet")28    lib = DecisionLibrary.from_runs(run_dirs)29    LIB.parent.mkdir(parents=True, exist_ok=True)30    lib.save(LIB)31    print(f"library: {len(lib)} recorded decisions from {len(run_dirs)} runs; features {FEATURES}")32    return lib333435def replay(seeds=(301, 302, 303, 304, 305), n_traders=1000, shares=(0.0, 0.25)):36    rows = []37    for n in (100, n_traders):38        act = {k: v * 100.0 / n for k, v in RunConfig().population.activity.items()}39        for share in shares:40            for s in seeds:41                cfg = RunConfig.from_yaml(ROOT / "configs/baseline.yaml", **{42                    "name": f"library_scale/n{n}_share{int(share * 100)}", "seed": s, "population.n_traders": n, "population.activity": act,43                    "population.llm_share": share, "population.llm.provider_mix": {"library": 1.0}, "population.llm.models": {"library": "knn-replay"},44                    "population.llm.frozen_library": str(LIB), "population.llm.usd_cap": 0.0, "population.llm.cache": False,45                    "treatment": {"arm": "library", "share": share, "n": n}})46                res = run_config(cfg, out_dir=OUT / f"n{n}_share{int(share * 100)}" / f"seed{s:04d}")47                oc = run_outcomes(res)48                oc["run_dir"] = str(OUT / f"n{n}_share{int(share * 100)}" / f"seed{s:04d}")49                rows.append(oc)50                print(f"  n={n} share={share} seed={s}: mad={oc['mad_pct']:.2f} spread={oc['spread_bp']:.1f} bubbles={oc['n_bubbles']} llm_vol={oc['llm_share_volume']:.3f} wall={oc['wall_s']:.1f}s", flush=True)51    df = pd.DataFrame(rows)52    OUT.mkdir(parents=True, exist_ok=True)53    df.to_parquet(OUT / "outcomes.parquet", index=False)54    print(df.groupby("name")[["mad_pct", "spread_bp", "n_bubbles", "max_dd", "llm_share_volume"]].mean().round(3))555657if __name__ == "__main__":58    build()59    replay()60
Files · b6c1d09b402a43e723c06ff0c9a6073a51ea3fa7
Menu

Theme