design_eth_robust_twap_live_plan.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from __future__ import annotations
  2. import argparse
  3. import json
  4. from pathlib import Path
  5. ROOT = Path(__file__).resolve().parents[1]
  6. REPORT_DIR = ROOT / "reports" / "eth-exploration"
  7. MARKDOWN_REPORT = REPORT_DIR / "eth-robust-twap-live-plan.md"
  8. JSON_REPORT = REPORT_DIR / "eth-robust-twap-live-plan.json"
  9. REQUIRED_SOURCE_FILES = (
  10. ROOT / "okx_codex_trader" / "okx_client.py",
  11. ROOT / "okx_codex_trader" / "cli.py",
  12. ROOT / "okx_codex_trader" / "paper_engine.py",
  13. ROOT / "freqtrade" / "README.md",
  14. ROOT / "freqtrade" / "user_data" / "strategies" / "BtcRsi2Guarded.py",
  15. ROOT / "scripts" / "search_eth_twap_robustness_10y.py",
  16. ROOT / "scripts" / "explore_ultrashort.py",
  17. REPORT_DIR / "eth-twap-robustness-10y-summary.md",
  18. REPORT_DIR / "eth-twap-robustness-10y-ranked.csv",
  19. )
  20. REQUIRED_MARKDOWN_HEADINGS = (
  21. "# ETH Robust Price TWAP 15m live execution plan",
  22. "## Signal clock",
  23. "## Entry orders",
  24. "## Partial fills",
  25. "## Exit and stop",
  26. "## State file",
  27. "## Minimum real-funds test",
  28. "## Commands and files",
  29. )
  30. REQUIRED_JSON_KEYS = (
  31. "strategy",
  32. "source_read",
  33. "signal_clock",
  34. "entry_orders",
  35. "partial_fills",
  36. "exit_and_stop",
  37. "state_file",
  38. "minimum_real_funds_test",
  39. "minimal_implementation_path",
  40. )
  41. def validate() -> list[str]:
  42. errors: list[str] = []
  43. for path in REQUIRED_SOURCE_FILES:
  44. if not path.exists():
  45. errors.append(f"missing source file: {path.relative_to(ROOT)}")
  46. if not MARKDOWN_REPORT.exists():
  47. errors.append(f"missing markdown report: {MARKDOWN_REPORT.relative_to(ROOT)}")
  48. else:
  49. text = MARKDOWN_REPORT.read_text(encoding="utf-8")
  50. for heading in REQUIRED_MARKDOWN_HEADINGS:
  51. if heading not in text:
  52. errors.append(f"missing markdown heading: {heading}")
  53. forbidden_phrases = ("place_order(", "/api/v5/trade/order", "confirm-live")
  54. for phrase in forbidden_phrases:
  55. if phrase in text:
  56. errors.append(f"report must not describe an executable order call: {phrase}")
  57. if not JSON_REPORT.exists():
  58. errors.append(f"missing json report: {JSON_REPORT.relative_to(ROOT)}")
  59. else:
  60. try:
  61. payload = json.loads(JSON_REPORT.read_text(encoding="utf-8"))
  62. except json.JSONDecodeError as exc:
  63. errors.append(f"json report is invalid: {exc}")
  64. else:
  65. if not isinstance(payload, dict):
  66. errors.append("json report root must be an object")
  67. else:
  68. for key in REQUIRED_JSON_KEYS:
  69. if key not in payload:
  70. errors.append(f"missing json key: {key}")
  71. return errors
  72. def main() -> int:
  73. parser = argparse.ArgumentParser()
  74. parser.add_argument("--json", action="store_true", help="print validation result as JSON")
  75. args = parser.parse_args()
  76. errors = validate()
  77. result = {
  78. "ok": not errors,
  79. "checked_reports": [
  80. str(MARKDOWN_REPORT.relative_to(ROOT)),
  81. str(JSON_REPORT.relative_to(ROOT)),
  82. ],
  83. "errors": errors,
  84. }
  85. if args.json:
  86. print(json.dumps(result, indent=2))
  87. elif errors:
  88. print("\n".join(errors))
  89. else:
  90. print("eth robust twap live plan static check passed")
  91. return 1 if errors else 0
  92. if __name__ == "__main__":
  93. raise SystemExit(main())