trader.py registers trend_rider_v9 (+ vt24/vt32/vt36) and trend_rider_v10 (+ vt32/vt36) from strategies/trend_rider_v9.py, and bridge.py labels them. These were left uncommitted by the 2026-10-07 research session while the monitor ran them from the working tree (state files data/trader_us_trend_rider_v9*/v10*). research/tr9_*.py is the research trail CLAUDE.md cites. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
94 lines
4.2 KiB
Python
94 lines
4.2 KiB
Python
"""Record every TrendRider V9 search trial on the official window.
|
|
|
|
The repo keeps an append-only trial log (DSR discipline): each searched
|
|
configuration is recorded with its result. This script re-runs the trial
|
|
set explored for V9 on the 2017-12-26..2026-09-30 engine window and appends
|
|
JSONL records to data/research/results/trials_us.jsonl.
|
|
|
|
PYTHONPATH=. uv run python -m research.tr9_trials [--dry-run]
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
|
|
from research.lab.trials import append_trials
|
|
|
|
import research.tr9_lab as lab
|
|
|
|
M = lab.TrendRiderV9
|
|
OUT = os.path.join("data", "research", "results", "trials_us.jsonl")
|
|
PROTOCOL = "tr9-v1-2026-10-07"
|
|
|
|
# (name, kwargs) — every configuration judged on the design window.
|
|
TRIALS = [
|
|
("v9_base(v7 replica)", {}),
|
|
("v9_soxl", {"risk_on": ("TQQQ", "UPRO", "TECL", "SOXL")}),
|
|
("v9_soxl_tna", {"risk_on": ("TQQQ", "UPRO", "TECL", "SOXL", "TNA")}),
|
|
("v9_tmf", {"tmf": "TMF"}),
|
|
("v9_sqqq", {"sqqq": "SQQQ"}),
|
|
("v9_tmf_sqqq", {"tmf": "TMF", "sqqq": "SQQQ"}),
|
|
("v9_park_qqq", {"pt_park_mix": {"SHY": 0.5, "QQQ": 0.5}}),
|
|
("v9_ladder", {"pt_mode": "ladder"}),
|
|
("v9_no_pt", {"pt_mode": "none"}),
|
|
("v9_assetvt", {"vt_mode": "asset"}),
|
|
("v9_ewma", {"vt_ewma": 20}),
|
|
("v9_momdiv", {"mom_pick_divisor": True}),
|
|
("v9_trail18", {"trail_pct": 0.18}),
|
|
("v9_trail22", {"trail_pct": 0.22}),
|
|
("v9_trail26", {"trail_pct": 0.26}),
|
|
("vt36", {"target_vol": 0.36, "min_lev": 0.75}),
|
|
("vt36_t18", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.18}),
|
|
("vt36_t19", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.19}),
|
|
("vt36_t20", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.20}),
|
|
("vt36_t21", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.21}),
|
|
("vt36_t22", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.22}),
|
|
("vt36_t23", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.23}),
|
|
("vt36_t24", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.24}),
|
|
("vt36_b15", {"target_vol": 0.36, "min_lev": 0.75, "pt_band": 0.15}),
|
|
("vt36_thr25", {"target_vol": 0.36, "min_lev": 0.75, "pt_threshold": 0.25}),
|
|
("vt36_thr35", {"target_vol": 0.36, "min_lev": 0.75, "pt_threshold": 0.35}),
|
|
("vt32_t18", {"target_vol": 0.32, "min_lev": 0.70, "trail_pct": 0.18}),
|
|
("vt32_t20", {"target_vol": 0.32, "min_lev": 0.70, "trail_pct": 0.20}),
|
|
("vt32_t22", {"target_vol": 0.32, "min_lev": 0.70, "trail_pct": 0.22}),
|
|
("vt34_t20", {"target_vol": 0.34, "min_lev": 0.72, "trail_pct": 0.20}),
|
|
("vt34_t22", {"target_vol": 0.34, "min_lev": 0.72, "trail_pct": 0.22}),
|
|
("vt38_t20", {"target_vol": 0.38, "min_lev": 0.78, "trail_pct": 0.20}),
|
|
("vt30_t20", {"target_vol": 0.30, "min_lev": 0.65, "trail_pct": 0.20}),
|
|
("vt24_t20", {"target_vol": 0.24, "min_lev": 0.50, "trail_pct": 0.20}),
|
|
("vt36_t20_w20", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.20, "trail_window": 20}),
|
|
("vt36_t20_w40", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.20, "trail_window": 40}),
|
|
("vt36_t22_r10", {"target_vol": 0.36, "min_lev": 0.75, "trail_pct": 0.22, "trail_reentry_days": 10}),
|
|
]
|
|
|
|
|
|
def main() -> None:
|
|
dry = "--dry-run" in sys.argv
|
|
names = []
|
|
for i, (label, kw) in enumerate(TRIALS):
|
|
name = f"tr9t{i:02d}_{label}"
|
|
lab.register(name, lambda kw=kw, **_: M(**kw))
|
|
names.append(name)
|
|
curves = lab.run(names)
|
|
rows = []
|
|
for i, (label, kw) in enumerate(TRIALS):
|
|
name = f"tr9t{i:02d}_{label}"
|
|
if name not in curves:
|
|
rows.append({"trial": label, "kwargs": kw, "error": "run failed"})
|
|
continue
|
|
m = lab.metrics(curves[name])
|
|
rows.append({"trial": label, "kwargs": {k: str(v) for k, v in kw.items()},
|
|
"cagr": m["cagr"], "vol": m["vol"], "sharpe": m["sharpe"], "mdd": m["mdd"],
|
|
"window": "2017-12-26..2026-09-30", "capital": 10000.0,
|
|
"fixed_fee": 2.0, "tx_cost": 0.001})
|
|
df = lab.report(curves, "trials")
|
|
if dry:
|
|
print("dry run: not writing", OUT)
|
|
return
|
|
append_trials(OUT, rows, PROTOCOL)
|
|
print(f"appended {len(rows)} trials to {OUT} (protocol {PROTOCOL})")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|