V3's output only includes {SPY, TQQQ, UPRO, GLD, DBC}. When PT
triggered, park_col resolved to "" (cash at 0%) instead of SHY.
Now injects SHY column before the PT loop if present in data.
Impact: ~0 in 2016-2026 (rising rates made SHY slightly negative),
but fixes ~0.6%/yr drag in normal rate environments (SHY ~4%/yr,
14.3% of days in PT-park).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DEFAULT_MONITOR_STRATEGIES now includes ALL strategies (stock + ETF)
instead of excluding ETF strategies. The cmd_morning/evening/auto
already route ETF strategies to the correct data pipeline via
strategy_universe() and strategy_data_market().
- Register trend_rider_v7, v7_vt24, v7_vt32 in bridge.py STRATEGY_META
so they appear in the stock-agent frontend via /api/strategies.
- Monitor now runs as a background daemon with logs written to
logs/monitor.log (PYTHONUNBUFFERED=1, no tmux dependency).
PID saved to logs/monitor.pid.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three-layer strategy for leveraged ETF portfolios:
Layer 1: V3 regime engine (MA150) — SPY technicals for risk-on/off
Layer 2: Vol-target overlay (28%, clip 0.6-1.0) — scale by realized vol
Layer 3: Profit-take with hysteresis (+30% → clear to SHY, restore <20%)
The profit-take exploits a structural property of 3x leveraged ETFs:
after large gains, volatility drag on the inflated base erodes compound
returns. Clearing the position locks in geometric gains before the drag
takes effect — this is rebalancing alpha, not prediction alpha.
10y backtest (2016-2026, 10bps one-way cost):
Ann 54.7%, Sharpe(rf=5%) 1.72, MaxDD -25.7%, Sortino 2.23
Also registers trend_rider_v7, trend_rider_v7_vt24, trend_rider_v7_vt32
in the trader strategy registry and ETF_STRATEGY_UNIVERSES.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add .qoder/ (local tool settings) and SEC fundamental data
(sec_frames/, sec_company_tickers.json) to prevent large
downloaded datasets from being tracked.
The existing framework fetches today's S&P 500 constituents from Wikipedia
and applies that list to the entire 10-year price history — classic
survivorship bias. Stocks that went bankrupt or were removed for poor
performance are absent, while today's winners (which may have been minor
names 10 years ago) are implicitly selected. This materially inflates
reported strategy returns.
New pipeline:
- universe_history.py reconstructs per-ticker membership intervals by
walking Wikipedia's "Selected changes" table backward from today.
- research/fetch_historical.py downloads prices for all 848 tickers
that were ever members (Yahoo returns ~675 of them; ~170 fully
delisted names are unavailable — remaining partial bias).
- research/pit_backtest.py masks prices to NaN outside membership
windows so strategies naturally cannot select non-members.
- research/strategies_plus.py adds RecoveryMomentumPlus (generalized
Recovery+Momentum with configurable weighting / blend / regime hook)
and an EnsembleStrategy.
- research/optimize.py runs five experiments: bias drift, hyperparameter
sweep (2016-2022 train / 2023-2026 test), SPY MA regime filter,
weighting schemes, and an uncorrelated-config ensemble.
Headline finding: the biased backtest reports 40.9% CAGR for
recovery_mom_top10 over 2016-2026; the point-in-time version reports
22.4% (vs 14.0% SPY buy-and-hold). True edge is ~8pp CAGR, not ~27pp.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add MARKET_FEES {us: 2, cn: 5} so the monitor and cron (auto) paths
automatically apply the correct local-currency fixed commission without
needing a per-strategy override. CLI --fixed-fee still wins when set
explicitly for auto; monitor now always resolves from the table so its
banner and each strategy sub-call agree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cmd_evening (used by the monitor path) only updated the simple daily_equity
dict, so daily_log had gaps on every monitor-driven day. Mirror cmd_auto's
pattern and call record_daily_snapshot so each strategy's NAV is recorded
every trading day, even when no trades execute.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New FactorComboStrategy class (strategies/factor_combo.py) implements
8 champion factor signals (4 US, 4 CN) discovered through iterative
factor research, each at 4 rebalancing frequencies (daily/weekly/
biweekly/monthly). Registered in trader.py as fc_{signal}_{freq}.
Existing strategies and state files are untouched — safe to git pull
and restart monitor on server.
Also includes factor research scripts (factor_loop.py, factor_research.py,
etc.) used to discover and validate these factors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>