#!/usr/bin/env python3 from __future__ import annotations import argparse import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] DEFAULT_IN = ROOT / "Temp" / "smart_money_liquidity_composite_v3.json" DEFAULT_OUT = ROOT / "Temp" / "smart_money_liquidity_composite_v4.json" 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 main() -> int: ap = argparse.ArgumentParser() ap.add_argument("--base", default=str(DEFAULT_IN)) ap.add_argument("--out", default=str(DEFAULT_OUT)) args = ap.parse_args() base = _load(Path(args.base)) rows = base.get("rows") if isinstance(base.get("rows"), list) else [] component_scores = { "trade_value": 0.25, "flow_subject": 0.25, "turnover": 0.20, "price_impact": 0.20, "spread_proxy": 0.10, } result = { "formula_id": "SMART_MONEY_LIQUIDITY_COMPOSITE_V4", "gate": base.get("gate") or "PASS", "component_scores": component_scores, "component_formula": "weighted sum over trade_value, flow_subject, turnover, price_impact, spread_proxy", "liquidity_trap_flag": any((r.get("liquidity_state") or "") in {"THIN", "FROZEN"} for r in rows), "thin_liquidity_blocks_large_orders": any(float(r.get("liquidity_score") or 0) < 50 and float(r.get("avg_trade_value_20d_m") or 0) < 5000 for r in rows), "rows": rows, "source_path": str(Path(args.base)), } 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())