#!/usr/bin/env python3 """EXECUTION_CAPACITY_LADDER_V1 — spec/formulas/domains/execution.yaml. Caps a planned order amount to the asset's actual fillable capacity and blocks the execution plan outright when the broker_microstructure_packet is incomplete. governance/todo/v8_9_p1_adoption_plan.yaml P1-B.2. """ from __future__ import annotations import argparse import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] DEFAULT_ORDERS = ROOT / "Temp" / "execution_capacity_orders_v1.json" DEFAULT_OUT = ROOT / "Temp" / "execution_capacity_ladder_v1.json" SPREAD_WIDEN_MULTIPLIER = 1.5 def _load(path: Path) -> dict: if not path.exists(): return {} try: data = json.loads(path.read_text(encoding="utf-8")) return data if isinstance(data, dict) else {} except Exception: return {} def evaluate_order_capacity(order: dict) -> dict: if order.get("halt_status") is True: return {**order, "gate": "EXECUTION_PLAN_BLOCKED", "reason_code": "trading_halt", "order_capacity_krw": None} required = ["avg_trade_value_20d_krw", "intraday_trade_value_krw", "orderbook_top3_depth_krw", "spread_bps"] if any(order.get(f) is None for f in required): return { **order, "gate": "EXECUTION_PLAN_BLOCKED", "reason_code": "broker_packet_missing", "order_capacity_krw": None, } planned = float(order.get("planned_order_amount_krw") or 0.0) capacity = min( planned, float(order["avg_trade_value_20d_krw"]) * 0.003, float(order["intraday_trade_value_krw"]) * 0.01, float(order["orderbook_top3_depth_krw"]) * 0.30, ) gate = "ORDER_SIZE_CAPPED" if capacity < planned else "PASS" return {**order, "gate": gate, "order_capacity_krw": capacity} def should_cancel_remaining_slices(current_spread_bps: float, baseline_spread_bps: float) -> bool: return current_spread_bps > baseline_spread_bps * SPREAD_WIDEN_MULTIPLIER def main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--orders", default=str(DEFAULT_ORDERS)) ap.add_argument("--out", default=str(DEFAULT_OUT)) args = ap.parse_args() doc = _load(Path(args.orders)) orders = doc.get("orders") if isinstance(doc.get("orders"), list) else [] rows = [evaluate_order_capacity(order) for order in orders if isinstance(order, dict)] result = { "formula_id": "EXECUTION_CAPACITY_LADDER_V1", "gate": "PASS" if rows else "DATA_MISSING", "rows": rows, "split_order_template": {"slice_1_pct": 30, "slice_2_pct": 30, "slice_3_pct": 40}, "source_paths": [str(Path(args.orders))], } out = Path(args.out) 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())