run_high_frequency_portfolio_observer.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from __future__ import annotations
  2. import argparse
  3. import json
  4. import sys
  5. import time
  6. from datetime import UTC, datetime
  7. from pathlib import Path
  8. sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
  9. from scripts import build_high_frequency_portfolio_observation_intent as intent
  10. ROOT = Path(__file__).resolve().parents[1]
  11. STATE_DIR = ROOT / "var" / "high-frequency-portfolio"
  12. def now_iso() -> str:
  13. return datetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z")
  14. def append_jsonl(path: Path, payload: dict[str, object]) -> None:
  15. path.parent.mkdir(parents=True, exist_ok=True)
  16. with path.open("a", encoding="utf-8") as handle:
  17. handle.write(json.dumps(payload, sort_keys=True, separators=(",", ":")) + "\n")
  18. def run_once(state_dir: Path) -> dict[str, object]:
  19. state_dir.mkdir(parents=True, exist_ok=True)
  20. payload = intent.build_payload()
  21. payload["created_at"] = now_iso()
  22. intent.REPORT_DIR.mkdir(parents=True, exist_ok=True)
  23. intent.OUTPUT_JSON.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
  24. intent.OUTPUT_MD.write_text(intent.markdown(payload), encoding="utf-8")
  25. (state_dir / "heartbeat.json").write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
  26. append_jsonl(state_dir / "observer-events.jsonl", payload)
  27. return payload
  28. def main() -> int:
  29. parser = argparse.ArgumentParser(description="Run high-frequency portfolio read-only observer.")
  30. parser.add_argument("--state-dir", type=Path, default=STATE_DIR)
  31. parser.add_argument("--interval-seconds", type=int, default=300)
  32. parser.add_argument("--once", action="store_true")
  33. args = parser.parse_args()
  34. while True:
  35. try:
  36. payload = run_once(args.state_dir)
  37. print(json.dumps(payload, indent=2, sort_keys=True))
  38. except Exception as exc:
  39. error = {"created_at": now_iso(), "mode": "high_frequency_portfolio_readonly_observer", "submitted_orders": 0, "error": str(exc)}
  40. append_jsonl(args.state_dir / "observer-events.jsonl", error)
  41. print(json.dumps(error, indent=2, sort_keys=True), file=sys.stderr)
  42. if args.once:
  43. return 1
  44. if args.once:
  45. return 0
  46. time.sleep(args.interval_seconds)
  47. if __name__ == "__main__":
  48. raise SystemExit(main())