Files
NexQuant/scripts/nexquant_rebacktest_parent.py
T
TPTBusiness cbe1c52e00 refactor: rename project from Predix to NexQuant
Rename all source files, scripts, tests, documentation, and configuration
from Predix/predix to NexQuant/nexquant across the entire codebase.
2026-05-09 17:48:22 +02:00

76 lines
2.7 KiB
Python

#!/usr/bin/env python
"""Parent orchestrator: calls nexquant_rebacktest_one.py for each strategy."""
import json, subprocess, sys
from pathlib import Path
from datetime import datetime
STRAT_DIR = Path("results/strategies_new")
# Build work list
work = []
for f in sorted(STRAT_DIR.glob("*.json")):
if "verified_v2" in f.read_text():
continue
try:
d = json.loads(f.read_text())
except Exception:
continue
if d.get("factor_names") and d.get("code"):
work.append(f)
print(f"{len(work)} strategies to re-backtest", flush=True)
ok = skip = fail = 0
start = datetime.now()
for i, f in enumerate(work):
name = f.stem[:45]
print(f"[{i+1}/{len(work)}] {name} ...", end=" ", flush=True)
try:
r = subprocess.run(
["timeout", "-s", "KILL", "90", "python", "scripts/nexquant_rebacktest_one.py", str(f)],
capture_output=True, text=True, timeout=120,
stdin=subprocess.DEVNULL,
)
result = json.loads(r.stdout.strip() or "{}")
except subprocess.TimeoutExpired:
print("TIMEOUT", flush=True)
fail += 1
continue
except Exception as e:
print(f"ERROR: {e}", flush=True)
fail += 1
continue
if result.get("status") == "ok":
data = json.loads(f.read_text())
data["reevaluation_status"] = "verified_v2"
data["sharpe_ratio"] = result.get("sharpe")
data["max_drawdown"] = result.get("max_drawdown")
data["win_rate"] = result.get("win_rate")
data["total_return"] = result.get("total_return")
data["summary"] = {
**data.get("summary", {}),
"sharpe": result.get("sharpe"),
"max_drawdown": result.get("max_drawdown"),
"win_rate": result.get("win_rate"),
"monthly_return_pct": result.get("monthly_return_pct"),
"real_n_trades": result.get("n_trades"),
"total_return": result.get("total_return"),
"annualized_return": result.get("annualized_return"),
"engine": "verified_v2",
"txn_cost_bps": 2.14,
}
f.write_text(json.dumps(data, indent=2, ensure_ascii=False))
ok += 1
print(f"S={result['sharpe']:.1f} DD={result['max_drawdown']:.2%} WR={result['win_rate']:.1%} T={result['n_trades']}", flush=True)
elif result.get("status") == "skipped":
skip += 1
print(f"SKIP: {result.get('reason', '?')}", flush=True)
else:
fail += 1
print(f"FAIL: {result.get('stderr', result.get('error', '?'))[:100]}", flush=True)
elapsed = (datetime.now() - start).total_seconds()
print(f"\nDONE: ok={ok} skip={skip} fail={fail} in {elapsed:.0f}s", flush=True)