mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
126 lines
No EOL
5.3 KiB
Python
126 lines
No EOL
5.3 KiB
Python
#!/usr/bin/env python3
|
|
# ==============================================================================
|
|
# COPYRIGHT NO ONE EVERYWHERE LLC (WYOMING HOLDING COMPANY)
|
|
# PROJECT: SOVEREIGN STACK
|
|
# This artifact is entirely proprietary and cryptographically proven.
|
|
# Open-Source usage requires explicit permission from Brandon Scott Schneider.
|
|
# ==============================================================================
|
|
"""Run paper-trading artifacts against a cycle directory with canonical paths."""
|
|
|
|
import argparse
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from scripts.paper_trading_simulator import (
|
|
finalize_one_page_summary,
|
|
run_fast_monte_carlo_sweep,
|
|
run_wall_clock_session,
|
|
)
|
|
except ModuleNotFoundError:
|
|
import sys
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
from paper_trading_simulator import (
|
|
finalize_one_page_summary,
|
|
run_fast_monte_carlo_sweep,
|
|
run_wall_clock_session,
|
|
)
|
|
|
|
|
|
def summary_filename() -> str:
|
|
"""Return the default one-page summary filename for the current UTC date."""
|
|
return f"one_page_summary_filled_{datetime.now(timezone.utc).date().isoformat()}.md"
|
|
|
|
|
|
def cycle_paths(cycle_dir: Path) -> dict[str, Path]:
|
|
"""Return canonical artifact locations inside a cycle packet."""
|
|
return {
|
|
"fast_sweep_output": cycle_dir / "01_strategy_outputs" / "fast_monte_carlo_sweep.json",
|
|
"wall_clock_report": cycle_dir / "01_strategy_outputs" / "wall_clock_session_report.json",
|
|
"wall_clock_heartbeat": cycle_dir / "01_strategy_outputs" / "wall_clock_heartbeat.log",
|
|
"review_heartbeat": cycle_dir / "01_strategy_outputs" / "review_heartbeat.log",
|
|
"summary_output": cycle_dir / "08_summary_report" / summary_filename(),
|
|
"reconciliation_ledger": cycle_dir / "07_allocation_ledger" / "reconciliation_ledger.csv",
|
|
}
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
"""Parse CLI arguments for cycle-oriented paper trading runs."""
|
|
parser = argparse.ArgumentParser(description="Cycle-oriented paper trading runner")
|
|
parser.add_argument(
|
|
"--mode",
|
|
choices=["fast-sweep", "wall-clock", "finalize-summary", "print-paths"],
|
|
required=True,
|
|
help="Workflow step to run",
|
|
)
|
|
parser.add_argument("--cycle-dir", required=True, help="Cycle directory root")
|
|
parser.add_argument("--initial-usdc", type=float, default=30000.0, help="Initial USDC capital")
|
|
parser.add_argument("--duration-hours", type=float, default=4.0, help="Duration in hours")
|
|
parser.add_argument("--tick-interval-seconds", type=float, default=60.0, help="Tick interval in seconds")
|
|
parser.add_argument("--heartbeat-every-ticks", type=int, default=5, help="Heartbeat write interval")
|
|
parser.add_argument("--sweep-count", type=int, default=25, help="Monte Carlo path count")
|
|
parser.add_argument("--seed", type=int, help="Optional random seed")
|
|
parser.add_argument("--review-log", help="Optional explicit review heartbeat path")
|
|
parser.add_argument("--reviewer", default="system-generated", help="Reviewer label for summary output")
|
|
parser.add_argument("--objective-target", type=float, default=30000.0, help="Objective target value")
|
|
parser.add_argument("--gross-exit-ceiling", type=float, default=37000.0, help="Gross exit ceiling")
|
|
return parser.parse_args()
|
|
|
|
|
|
def main() -> None:
|
|
"""Entry point for canonical cycle runs."""
|
|
args = parse_args()
|
|
cycle_dir = Path(args.cycle_dir)
|
|
paths = cycle_paths(cycle_dir)
|
|
review_log_path = Path(args.review_log) if args.review_log else paths["review_heartbeat"]
|
|
|
|
if args.mode == "print-paths":
|
|
for key, value in paths.items():
|
|
print(f"{key}={value}")
|
|
return
|
|
|
|
if args.mode == "fast-sweep":
|
|
run_fast_monte_carlo_sweep(
|
|
initial_usdc=args.initial_usdc,
|
|
duration_hours=args.duration_hours,
|
|
tick_interval_seconds=args.tick_interval_seconds,
|
|
sweep_count=args.sweep_count,
|
|
output_path=paths["fast_sweep_output"],
|
|
seed=args.seed,
|
|
)
|
|
return
|
|
|
|
if args.mode == "wall-clock":
|
|
run_wall_clock_session(
|
|
initial_usdc=args.initial_usdc,
|
|
duration_hours=args.duration_hours,
|
|
tick_interval_seconds=args.tick_interval_seconds,
|
|
heartbeat_every_ticks=args.heartbeat_every_ticks,
|
|
output_path=paths["wall_clock_report"],
|
|
heartbeat_path=paths["wall_clock_heartbeat"],
|
|
cycle_dir=cycle_dir,
|
|
review_log_path=review_log_path if review_log_path.exists() else None,
|
|
summary_output_path=paths["summary_output"],
|
|
reviewer=args.reviewer,
|
|
objective_target=args.objective_target,
|
|
gross_exit_ceiling=args.gross_exit_ceiling,
|
|
seed=args.seed,
|
|
)
|
|
return
|
|
|
|
summary_path = finalize_one_page_summary(
|
|
cycle_dir=cycle_dir,
|
|
session_report_path=paths["wall_clock_report"],
|
|
heartbeat_log_path=paths["wall_clock_heartbeat"],
|
|
review_log_path=review_log_path if review_log_path.exists() else None,
|
|
summary_output_path=paths["summary_output"],
|
|
reviewer=args.reviewer,
|
|
objective_target=args.objective_target,
|
|
gross_exit_ceiling=args.gross_exit_ceiling,
|
|
)
|
|
print(f"summary_output={summary_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |