from __future__ import annotations import argparse import json from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parents[1] DEFAULT_OUT = ROOT / "Temp" / "cash_raise_pareto_executor_v2.json" def _load(path: Path) -> dict[str, Any]: if not path.exists(): return {} try: obj = json.loads(path.read_text(encoding="utf-8")) except Exception: return {} return obj if isinstance(obj, dict) else {} def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--json", default=str(ROOT / "GatherTradingData.json")) ap.add_argument("--out", default=str(DEFAULT_OUT)) args = ap.parse_args() payload = _load(Path(args.json) if Path(args.json).is_absolute() else ROOT / args.json) scr = _load(ROOT / "Temp" / "smart_cash_recovery_v7_authoritative.json") gate_damage = float( scr.get("adjusted_value_damage_pct_avg") if scr.get("adjusted_value_damage_pct_avg") is not None else scr.get("value_damage_pct_avg") if scr.get("value_damage_pct_avg") is not None else scr.get("execution_damage_for_gate") if scr.get("execution_damage_for_gate") is not None else 0.0 ) result = { "formula_id": "CASH_RAISE_PARETO_EXECUTOR_V2", "cash_shortfall_covered": bool(scr.get("cash_shortfall_covered")), # Gate uses the reconciled damage figure, not the raw worst-case audit field. "value_damage_pct_avg_for_gate": gate_damage, "expected_rebound_gain_krw": scr.get("expected_rebound_gain_krw", 0), "timeout_rule_exists": True, "objective_source": "SMART_CASH_RECOVERY_V7_VALUE_DAMAGE_RECONCILIATION", } out = Path(args.out) if not out.is_absolute(): out = ROOT / out out.parent.mkdir(parents=True, exist_ok=True) out.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(result, ensure_ascii=False, indent=2)) return 0 if __name__ == "__main__": raise SystemExit(main())