from __future__ import annotations import argparse import json import sys import time from datetime import UTC, datetime from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from scripts import build_high_frequency_portfolio_observation_intent as intent ROOT = Path(__file__).resolve().parents[1] STATE_DIR = ROOT / "var" / "high-frequency-portfolio" def now_iso() -> str: return datetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") def append_jsonl(path: Path, payload: dict[str, object]) -> None: path.parent.mkdir(parents=True, exist_ok=True) with path.open("a", encoding="utf-8") as handle: handle.write(json.dumps(payload, sort_keys=True, separators=(",", ":")) + "\n") def run_once(state_dir: Path) -> dict[str, object]: state_dir.mkdir(parents=True, exist_ok=True) payload = intent.build_payload() payload["created_at"] = now_iso() intent.REPORT_DIR.mkdir(parents=True, exist_ok=True) intent.OUTPUT_JSON.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") intent.OUTPUT_MD.write_text(intent.markdown(payload), encoding="utf-8") (state_dir / "heartbeat.json").write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8") append_jsonl(state_dir / "observer-events.jsonl", payload) return payload def main() -> int: parser = argparse.ArgumentParser(description="Run high-frequency portfolio read-only observer.") parser.add_argument("--state-dir", type=Path, default=STATE_DIR) parser.add_argument("--interval-seconds", type=int, default=300) parser.add_argument("--once", action="store_true") args = parser.parse_args() while True: try: payload = run_once(args.state_dir) print(json.dumps(payload, indent=2, sort_keys=True)) except Exception as exc: error = {"created_at": now_iso(), "mode": "high_frequency_portfolio_readonly_observer", "submitted_orders": 0, "error": str(exc)} append_jsonl(args.state_dir / "observer-events.jsonl", error) print(json.dumps(error, indent=2, sort_keys=True), file=sys.stderr) if args.once: return 1 if args.once: return 0 time.sleep(args.interval_seconds) if __name__ == "__main__": raise SystemExit(main())