feat: register V7+VT36 as SOTA and add monitor hot-reload
- Register trend_rider_v7_vt36 (target_vol=0.36, min_lev=0.75) in strategy registry, ETF universe map, and bridge metadata. 10y backtest: Ann 60.5%, Sharpe 1.87, MaxDD -29.2%. - Add hot-reload to monitor: each phase re-imports trader module to pick up newly registered strategies without restart. New strategies are logged on detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -380,6 +380,12 @@ STRATEGY_META = {
|
||||
"params": {},
|
||||
"markets": ["us"],
|
||||
},
|
||||
"trend_rider_v7_vt36": {
|
||||
"label": "Trend Rider V7 (VT36% + PT30) ★ SOTA",
|
||||
"category": "tactical_allocation",
|
||||
"params": {},
|
||||
"markets": ["us"],
|
||||
},
|
||||
# --- Stock-picker ensembles (US S&P 500 universe) ---
|
||||
"ensemble_alpha_top10": {
|
||||
"label": "Ensemble Alpha Top 10",
|
||||
|
||||
27
trader.py
27
trader.py
@@ -178,6 +178,7 @@ STRATEGY_REGISTRY = {
|
||||
"trend_rider_v7": lambda **kw: TrendRiderV7(),
|
||||
"trend_rider_v7_vt24": lambda **kw: TrendRiderV7(target_vol=0.24, min_lev=0.5),
|
||||
"trend_rider_v7_vt32": lambda **kw: TrendRiderV7(target_vol=0.32, min_lev=0.7),
|
||||
"trend_rider_v7_vt36": lambda **kw: TrendRiderV7(target_vol=0.36, min_lev=0.75),
|
||||
# --- Stock-picker ensemble strategies (S&P 500 universe) ---
|
||||
"ensemble_alpha_top10": lambda **kw: EnsembleAlphaStrategy(top_n=10),
|
||||
"ensemble_alpha_top12": lambda **kw: EnsembleAlphaStrategy(top_n=12),
|
||||
@@ -222,6 +223,7 @@ ETF_STRATEGY_UNIVERSES = {
|
||||
"trend_rider_v7": sorted(set(ETF_UNIVERSE)),
|
||||
"trend_rider_v7_vt24": sorted(set(ETF_UNIVERSE)),
|
||||
"trend_rider_v7_vt32": sorted(set(ETF_UNIVERSE)),
|
||||
"trend_rider_v7_vt36": sorted(set(ETF_UNIVERSE)),
|
||||
}
|
||||
|
||||
# Strategies that use the market's stock universe PLUS fixed extra ETF tickers.
|
||||
@@ -1296,6 +1298,7 @@ def cmd_monitor(args):
|
||||
print(f" Evening: {sched['eve_h']:02d}:{sched['eve_m']:02d} {sched['tz']}")
|
||||
print(f" Fixed fee: {fee:.2f}/trade")
|
||||
print(f" Strategies: {', '.join(strategies)}")
|
||||
print(f" Auto-reload: ON (new strategies picked up each phase)")
|
||||
print(f"{'='*60}")
|
||||
|
||||
# Use UTC as common reference for sleeping
|
||||
@@ -1328,12 +1331,34 @@ def cmd_monitor(args):
|
||||
all_candidates.extend(_next_events_for_market(mkt, now_utc))
|
||||
return min(all_candidates, key=lambda x: x[0])
|
||||
|
||||
def _reload_strategies():
|
||||
"""Re-read STRATEGY_REGISTRY to pick up new strategies without restart."""
|
||||
import importlib
|
||||
import trader as _self_mod
|
||||
importlib.reload(_self_mod)
|
||||
current = list(_self_mod.STRATEGY_REGISTRY.keys())
|
||||
return current, _self_mod.STRATEGY_REGISTRY
|
||||
|
||||
def _run_phase(market, phase, now_utc):
|
||||
"""Run all strategies for a market/phase."""
|
||||
nonlocal strategies
|
||||
sched = market_schedules[market]
|
||||
tz = sched["tz"]
|
||||
now_local = now_utc.astimezone(tz)
|
||||
|
||||
# Hot-reload strategy list from registry
|
||||
try:
|
||||
reloaded_names, reloaded_reg = _reload_strategies()
|
||||
new_strats = set(reloaded_names) - set(strategies)
|
||||
if new_strats:
|
||||
print(f"[monitor] Hot-reload: +{len(new_strats)} new strategies: "
|
||||
f"{', '.join(sorted(new_strats))}")
|
||||
strategies = reloaded_names
|
||||
# Update the global registry so cmd_morning/cmd_auto use new strategies
|
||||
globals().update({"STRATEGY_REGISTRY": reloaded_reg})
|
||||
except Exception as e:
|
||||
print(f"[monitor] Hot-reload failed (using cached list): {e}")
|
||||
|
||||
print(f"\n[monitor] {'='*55}")
|
||||
print(f"[monitor] {market.upper()} {phase.upper()} at "
|
||||
f"{now_local.strftime('%Y-%m-%d %H:%M:%S %Z')}")
|
||||
@@ -1370,7 +1395,7 @@ def cmd_monitor(args):
|
||||
traceback.print_exc()
|
||||
|
||||
print(f"[monitor] {market.upper()} {phase} done — "
|
||||
f"{len(strategies)} strategies")
|
||||
f"{len(strategies)} strategies\n")
|
||||
|
||||
while True:
|
||||
now_utc = datetime.now(utc)
|
||||
|
||||
Reference in New Issue
Block a user