| 53 | |
| 54 | |
| 55 | def _write_run_artifacts( |
| 56 | run_dir: Path, |
| 57 | *, |
| 58 | run_name: str, |
| 59 | config_path: Path, |
| 60 | manifest_cfg: dict, |
| 61 | dataset_meta: dict, |
| 62 | out: dict, |
| 63 | ) -> None: |
| 64 | run_dir.mkdir(parents=True, exist_ok=True) |
| 65 | summary_df: pl.DataFrame = out["summary"] |
| 66 | summary_df.write_parquet(run_dir / "metrics.parquet") |
| 67 | out["frames"]["events"].write_parquet(run_dir / "events.parquet") |
| 68 | out["frames"]["signals"].write_parquet(run_dir / "signals.parquet") |
| 69 | out["frames"]["weights"].write_parquet(run_dir / "weights.parquet") |
| 70 | out["frames"]["backtest"].write_parquet(run_dir / "backtest.parquet") |
| 71 | |
| 72 | run_manifest = openquant.research.research_run_manifest( |
| 73 | manifest_cfg, |
| 74 | dataset_meta={**dataset_meta, "config_path": str(config_path)}, |
| 75 | ) |
| 76 | manifest = { |
| 77 | "run_name": run_name, |
| 78 | "config_path": str(config_path), |
| 79 | "config_digest": run_manifest["config_digest"], |
| 80 | "git_sha": _git_sha(REPO_ROOT), |
| 81 | "python": sys.version.split()[0], |
| 82 | "openquant_package": "openquant (local editable)", |
| 83 | "dataset": dataset_meta, |
| 84 | "config": manifest_cfg, |
| 85 | } |
| 86 | (run_dir / "run_manifest.json").write_text(json.dumps(manifest, indent=2), encoding="utf-8") |
| 87 | |
| 88 | promotion = out["promotion"] |
| 89 | decision_lines = [ |
| 90 | f"# Promotion Decision: {run_name}", |
| 91 | "", |
| 92 | f"- promote_candidate: `{promotion['promote_candidate']}`", |
| 93 | f"- passed_realized_sharpe: `{promotion['passed_realized_sharpe']}`", |
| 94 | f"- passed_net_sharpe: `{promotion['passed_net_sharpe']}`", |
| 95 | f"- passed_alignment_guard: `{promotion['passed_alignment_guard']}`", |
| 96 | f"- passed_event_order_guard: `{promotion['passed_event_order_guard']}`", |
| 97 | "", |
| 98 | "## Cost Snapshot", |
| 99 | f"- turnover: `{out['costs']['turnover']:.6f}`", |
| 100 | f"- realized_vol: `{out['costs']['realized_vol']:.6f}`", |
| 101 | f"- estimated_total_cost: `{out['costs']['estimated_total_cost']:.6f}`", |
| 102 | f"- gross_total_return: `{out['costs']['gross_total_return']:.6f}`", |
| 103 | f"- net_total_return: `{out['costs']['net_total_return']:.6f}`", |
| 104 | f"- net_sharpe: `{out['costs']['net_sharpe']:.6f}`", |
| 105 | ] |
| 106 | (run_dir / "decision.md").write_text("\n".join(decision_lines) + "\n", encoding="utf-8") |
| 107 | |
| 108 | |
| 109 | def run(config_path: Path, out_root: Path) -> Path: |