Removed (79 files, all in history; research/ARCHIVE.md lists each with its
purpose and the commit to restore it from):
- root factor_*.py mining scripts (2026-04) and yearly_sweep.py
- scripts/run_daily.{py,sh} (superseded by the monitor service; no crontab)
- strategies no registry, test or live book uses: trend_rider_v8,
adaptive_blend, cross_asset_momentum, long_hedged, ls_momentum
- 55 research/*.py scripts from 2026-04/05 written before research/lab,
the us-alpha design spec, and the 7 tests that only covered them
Kept research/permanent_yearly.py: bridge.py and precompute_backtest.py
import equity_with_cashflows. CLAUDE.md gains the archive note and the
command lines of the studies committed in the previous commit.
Checks: 99 unit tests OK (125 before, minus the 26 removed with their
modules), all 157 remaining modules import, 94 registry strategies build,
bridge.py list OK, web 23 tests OK and build OK.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Studies run by earlier sessions and documented in CLAUDE.md, but never
committed: FINRA short volume (SVR) and the research-only svr_momentum veto,
SEC fails-to-deliver, 13D activists and the 13D event sleeve, 13F
institutional flow, GDELT news volume, S&P 400/600 Form 4 insiders,
union_shield, shield_lab; plus the mid/small insider and Tiingo fetcher
changes and midsmall_rebuild.
overnight_midsmall: the overnight-only momentum book on S&P 400/600 earns
0.93 net Sharpe at 3 bp a side (2019-26) with corr 0.83 to the S&P 500 book
(STOP).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Share point-in-time signals and a cash-funded order ledger across backtests and trading. Correct eligibility, missing-price fills, quality factors, regime inputs, warmup windows, and cash-injection accounting. Add reproducible registered-strategy comparisons and paired forward candidates with a 20% resize band.
Validation: 125 Python tests, 23 web tests, TypeScript/Vite build, 87 strategy causality checks, and real-data target/order/equity parity for 10 strategies.
overnight_recovery_agent_top10 (strategies/agent_review.py) re-ranks the
overnight_recovery top 50 with an LLM agent's daily scores:
final = quant percentile + 0.25 x score (-2..+2), vetoes for five event types,
top 10 on the base strategy's rebalance rows and hysteresis. Score files are
stamped by `agent_review.py submit` and steer a session only if stamped before
its 16:00 New York close; without one the strategy holds exactly what
overnight_recovery_top10 holds (checked on the live panel 2016-2026).
- agent_review.py: candidates / submit / evaluate; skill
.claude/skills/agent-stock-review drives the daily research.
- US only, skipped by precompute (no history before its first score file);
runs in the original book and in selected_2026_09 (from the book's start).
- .gitignore tracks .claude/skills/ and ignores data/agent/.
Monitor fix: hot-reload re-imports trader.py but not strategies/*. After the
2026-09-29 strategy commits the stale modules made every phase's panel refresh
fail ("Unknown signal 'low_risk'") and US books skipped 09-29 until a restart.
_reload_strategies now builds every factory and keeps the old registry when
any fails; CLAUDE.md says to restart the monitor after changing strategy code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Register us_momentum_qqq_trend: half overnight_recovery_top10, half a QQQ
trend sleeve (strategies/qqq_trend.py: 200-day switch times a 30% vol target,
held as TQQQ + SHY). Mixed stock+ETF, US only (extra tickers QQQ, SHY, TQQQ).
Research (research/lab/): alpha against QQQ with a 2006-16 design / 2017-26
holdout split (alpha.py, qqq_scan.py, beat_qqq.py); leverage and drawdown
frontier (levered_book.py, us_target50.py); synthetic 3x ETFs from 1990 and
TrendRider/QQQ-trend stress tests (fetch_long_history.py, letf_history.py,
vol_trend.py); short-horizon sleeves, diversifiers, industry momentum,
earnings-announcement returns; new point-in-time data sources: SEC Form 4
insider trades (fetch_insider.py, insider.py), 10-K/10-Q text similarity,
8-K earnings dates and SIC codes (fetch_lazy_prices.py, lazy_prices.py), and
an S&P 400/600 universe from iShares holdings (fetch_us_mid.py, panel_mid.py).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Register two live strategies from the 2026-09-29 US research:
- lowrisk_top20: idiosyncratic vol + low beta, top 20, monthly, buffer 2
(new `low_risk` signal in strategies/robust_momentum.py)
- us_three_sleeve: 1/3 each of overnight_recovery_top10, lowrisk_top20 and
trend_rider_v7_vt24 in one account (strategies/sleeve_portfolio.py, a
mixed stock+ETF strategy). Sleeve shares drift with their returns and reset
at a month start once any is >25% off its share.
Research (research/lab, S&P 500 PIT, next-open fills):
- rotation.py / persistence.py: walk-forward factor weighting (factor
momentum, rolling IC, market state) and last-year's-winner selection do not
beat a fixed composite
- us_sweep.py: holdings count, z/vol weights, dynamic N, tranching and market
overlays (Faber SMA, de-risk vol target, statistical jump model,
momentum state); engine.py gains zvol weighting and dyn_n
- fetch_us_fundamentals.py / fundamentals.py / fund_eval.py: SEC EDGAR
point-in-time fundamentals (first-filed values) and factor tests
- trend_rider_long.py / us_final.py: 2010-2026 TrendRider curves and the
3-sleeve check (2011-2026 Sharpe 1.21, CAGR 21.9%, MaxDD -23%)
Web-UI engine, 2017-09..2026-09, $2/order: us_three_sleeve CAGR 28.9%,
Sharpe 1.49, MaxDD -24.8%.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Strategies
- BarStrategy protocol (close/open/high/low/volume bars; row d uses bars
through d-1) and RobustMomentumStrategy: overnight_recovery_top10 (US),
lowrisk_momentum_top15 and lowbeta_sharpe_mom_top20 (CN), top-N with
rank hysteresis, 10-day rebalance, weights drift between rebalances.
- trader: strategy_fields/strategy_bars/bar_session_weights; one signal
path (_signals_for_sessions) replaces generate_target_weights.
Live fixes
- CSI 300 constituents come from China Securities Index's file; the
Wikipedia table was 122 names off the real index.
- S&P 500 change log moved to "Historical components of the S&P 500".
- data_manager: tickers missing from a partial Yahoo batch are retried
alone before being marked unavailable (CEG, GEV, SNDK ... were dropped).
update() takes fields=[...] and stores high/low/volume panels.
- Whole-lot orders go to the nearest lot within cash (CN books held ~62%
cash); held names are resized only beyond RESIZE_BAND (10%), so books no
longer pay a ticket fee to trade daily drift.
Web backtests
- backtest_runner.py replaces the duplicated bridge/precompute code: PIT
membership in both markets (data/csi300_history.json), stock universe
limited to index members (ETFs and benchmarks in the shared panel were
pickable), and the book kept like the live trader (simulate_live_book:
signal timing, drift, order floor, resize band, fees on orders placed).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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>
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>
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>
Backtesting engine supporting 11 strategies across US (S&P 500) and CN (CSI 300)
markets with open-to-close execution, proportional + fixed per-trade fees.
Daily trader (trader.py) with auto/morning/evening/simulate/status commands
and cron-friendly `auto` mode for unattended daily runs on a server.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>