- execution/trader: a held US stock with no print for 5 sessions that has left
the index is sold at its last print (execution.SETTLE_AFTER_SESSIONS), in both
the batch replay and the live session ledger. Acquired names used to stay at
their last mark forever: lowrisk_top20 ended 2017-12..2026-10 with 11 of 26
dead positions, and CAGR rises 1.7-5.5pp once they settle. ENGINE_VERSION
cash-ledger-pit-v3; the API cache key follows.
- universe_history: current members whose pre-2011 addition the Wikipedia change
log missed now start at the list page's "Date added" (80 of 94 current members
added 2001-2010 were open-start, e.g. ISRG, MA, BKNG). Membership from 2016 on
is unchanged; the research panel cache now keys on the membership intervals.
- research/lab/registered: pure-ETF strategies replay on the ETF panel (they ran
as all-cash books or crashed); prepare_strategy refuses an ETF strategy that
lacks its ETF universe.
- research/lab/factors: trend_hzz uses a month's regression betas only from the
session its forward returns end (short months read 1-2 sessions ahead).
- tests: every registered strategy (US and CN) is truncation-invariant on the
production signal path; batch and live ledgers settle a delisting identically.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Buying the biggest overnight losers at 09:35 and selling at the close earns
1-6 bp a day gross on 2016-26 Alpaca 5-min bars; net Sharpe ~0, and stacking
it on the overnight sleeve lowers the Sharpe (1.27 -> ~0.8).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- overnight_book: swapping the all-day momentum sleeve for the overnight-only
one lifts the three-sleeve book from Sharpe 0.98 to 1.38 (halves 1.16/1.64)
and MaxDD from -37% to -17% at 1 bp a side; at 4 bp the gain is gone.
- overnight_book_mf: at the leverage for 50%/yr, a DBMF sleeve leaves the
levered MaxDD unchanged (~-36%) and needs more leverage; no CTA sleeve.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- orb_stocks_in_play: 5-min bounds -70%/yr (conservative) vs +71%/yr
(optimistic); the optimistic bound breaks even at 3.6 bp slippage a side.
- overnight_only: the momentum sleeve's names earn their return overnight
(Sharpe 1.57) and nothing intraday; held close->open only, net Sharpe
1.29-1.42 at 1 bp a side, below the 1.5 gate.
- overnight_paper.py + systemd unit: MOC buy / MOO sell of the top 10 on the
Alpaca paper account from 2026-10-12, with a fills-vs-prints report.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hedged_momentum: overnight_recovery_top10 hedged with QQQ futures at a
rolling 126d beta earns Sharpe 0.11; alpha vs QQQ on the Tiingo panel is
+5.3%/yr (t 1.10). futures_trend: Yahoo =F data is roughly usable (ES/NQ
corr 0.98, ZN/GC miss on settlement time), 24-market TSMOM Sharpe 0.44,
corr 0.22 with TrendRider: a crisis diversifier, not a core stream.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preregistered: inverse-vol shares of momentum, lowrisk, TrendRider V10
(synthetic 3x ETFs, lag fills), 8-ETF TSMOM and BTC trend, 2006-10..2026-09.
invvol5 1x: 12.6%/yr, Sharpe 1.07, MaxDD -18% (halves 0.82/1.38) beats the
three-sleeve book (0.97, -38%) but not TrendRider V10 in 2017-26 (1.65);
levered to 25% vol it drops to 0.98. Inverse vol over-weights the weakest
streams; the bottleneck is stream Sharpe, not weighting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preregistered replication vs IJR, 2017-01..2026-09, 20bp decides:
quality composite +2.3%/yr (t 0.78; halves +8.0/-3.5), quality-filtered
momentum +2.2% (t 0.73); SUE and lottery-filtered momentum also REJECT,
all weaker at 40bp. Equal-weight members beat IJR (t 3.2) and every
sleeve. Decision: drop quality stock selection in mid/small caps.
Adds --universe small to fetch_us_fundamentals (IJR, name-checked CIKs),
a `which` argument to fundamentals.load_mid, and --universe small to
midcap_sleeve.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After S&P 400 names failed inside the large-cap momentum top 10, test them
as their own sleeve: top 30, monthly, buffer 1, 20 bp, judged by alpha vs
IJH and by whether 1/3 of the book in the sleeve beats 1/3 in IJH. Four
hypotheses and a control, definitions and rule written before the run.
Holdout 2017-01..2026-09: mid-cap momentum -1.0%/yr vs IJH (corr 0.83 with
the large-cap book), lottery-excluded momentum -1.7%, SUE earnings momentum
-1.7%, quality-screened momentum +3.5% (t 1.28), quality composite +3.4%
(t 1.23; book 0.91 vs 0.85 with IJH). Quality is positive in both halves
but underpowered; nothing is adopted.
fetch_us_fundamentals gains --universe mid: EDGAR facts for S&P 400
ever-members, CIKs accepted only when an SEC name matches the iShares
holding name. fundamentals.load_mid builds the same factors on that panel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Yahoo purges delisted members: the S&P research panel was missing 209
ever-members (AGN/CELG/ESRX/ATVI/TWTR/XLNX/...), the production store 89, and
the S&P 400/600 panels ~180 more. The gap inflated momentum-family factors
(overnight_mom holdout 16.9->14.8%/yr, rec_126 14.7->10.7 on the research
panel; factor_panel_check).
research/lab/fetch_tiingo.py pulls full EOD histories (free tier: 500 unique
symbols/month, 50/hour; paced, resume-safe, key never logged).
research/lab/tiingo_merge.py overlays the caches on the research S&P panel at
build time (>=50% PIT-coverage gate, median-overlap cross-check, stub-column
replacement, rename splices GPS<-GAP, DISCA<-WBD, WLTW<-WTW, ADS<-BFH,
CCE<-CCEP, ESV<-VAL, FBHS<-FBIN, HFC<-DINO) and can apply the same to the
production store (--production [--apply]; data/us*.csv, .bak-tiingo backups,
under the panel lock). load_us() rebuilds when the overlay changes
(_tiingo_sig); fetch_us_mid.load_bars falls back to converted CSVs.
Round 1 (2026-10-08): 165/209 S&P names and 183 mid/small PIT members
restored (2011-19 snapshots were 15-20% short of PIT members). prod_impact
A/B on registered replays: overnight_recovery_top10 23.8%/0.83/-38.3% vs
27.8%/0.88/-47.3% backfill-off; lowrisk_top20 6.1%/0.58 vs 8.6%/0.60 -
honest long returns with shallower drawdowns; trend_rider_v10 (ETF path)
unchanged at 55.0%/1.64. Official precompute refreshed (backup at
data/precomputed/backtest_results.json.pretiingo). midsmall_scan on the
corrected panel: no factor beats the EW benchmark (0.60 holdout Sharpe vs
0.51-0.52 best) - no mid/small sleeve.
LITE ranked #1-4 on the overnight_recovery score from 2025-07 while still an
S&P 400 member, and the book could only buy it after it joined the S&P 500
on 2026-03-23. research/lab/universe_midcap.py tests whether ranking S&P 400
members alongside the S&P 500 helps, on one merged panel with one engine and
20 bp a side for every arm; the decision rule is written before the run.
Primary window 2019-01..2026-09: union Sharpe 0.86 / CAGR 24.7% / MaxDD
-38.8% vs base 0.98 / 29.4% / -34.3%; 2019-24 alone 0.48 vs 0.70; without
PENN, LITE and SMCI the union's alpha vs base is -6.7%/yr (t -2.1). Mid-cap
momentum adds a few large winners and many small losers. Not adopted.
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.
Tests of the "rank and buy top N misses the chain / cycle / sentiment" question
(report: https://claude.ai/artifact/HUnPtcy7D7Zp1yNQsDLRHY):
- review_live_us: Apr-Sep 2026 replay; book return vs AI-chain weight corr 0.71,
overnight_recovery_top10 excess almost all allocation (memory stage +28pp).
- fetch_supply_links: 10-K mentions of S&P 1500 companies by role, PIT by filing
date (12,117 S&P 500 10-Ks; --universe mid for 14,382 S&P 400/600 10-Ks).
- lead_lag: corr-peer and 10-K link momentum worked 2006-16 (FM t 3.3-4.3) and
vanished 2017-26 (t -2.1..-0.6); Granger lead-lag network and earnings
spillover drift null after 2016.
- theme_propagation: linked laggards of each era's hot industry underperform
2017-26 (-2% to -12%/yr).
- lead_lag_small: the same signals on S&P 400/600, 2019-26, all |t| <= 1.8.
- sector_cycle: 21 cycle/rotation variants, none with holdout |t| > 2.
- fetch_wiki_attention + attention: Wikipedia pageview attention, |IC| <= 0.013.
- concentration: industry caps on momentum top 10 cut alpha, not drawdown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Stop tracking data/sp500_history.json (rebuilt daily from Wikipedia by
universe_history.load_sp500_history) and ignore data/books/ (per-machine
live book state, like data/trader_*.json).
- research/lab/momentum_fundamentals.py: financial-statement vetoes and
confirmations on overnight_recovery_top10 (2011-16 design, 2017-26
holdout). No return gain; re-sorting the momentum top 30 by fundamental
momentum lowers MaxDD at equal return.
Co-Authored-By: Claude Opus 5.5 (1M context) <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>
Event-driven long-only simulator with next-open fills, CN tradability
(halts, limit-up/down, stamp duty), PIT S&P 500 / CSI 300 membership,
rebalance-phase averaging, factor IC scans, maximin stepwise composite
search across 5-year blocks, walk-forward LightGBM/ridge combiners,
overlays, and deflated Sharpe. Fetchers pull 20y US OHLCV from Yahoo and
CSI 300/500 ever-members (membership snapshot from baostock, bars from
Yahoo). Research data lives in data/research/ (ignored).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Four research directions beyond V7+VT36:
1. single_stock_swing: 20 famous stocks (Mag 7 + others), per-stock
optimized swing trading. High-vol growth stocks (AMD Sharpe 1.55,
TSLA 1.54) work best, but overfitting risk is extreme — universal
params only TSLA is viable. Not competitive with V7.
2. v7_literature_alpha: 9 academic directions (VIX overlay, Kelly
sizing, multi-MA, cross-asset, momentum acceleration, VIX mean-
reversion, vol-adaptive PT, combined). V3's regime engine already
implicitly captures most literature signals. MA130 marginally
better than MA150 (+0.02 Sharpe, within noise).
3. new_frameworks_eval: volatility trading (SVXY risk-off) and
calendar effects (turn-of-month). SVXY and V7 regime structurally
conflict — SVXY crashes exactly when V7 goes risk-off.
Turn-of-month has decent Sharpe (1.30) but only 28% annual.
Nothing beats V7.
4. smart_dca_eval: fixed/VIX-scaled/MA-deviation/value-averaging/RSI
DCA into SPY/QQQ/TQQQ/UPRO + V7 hybrids. Smart DCA barely beats
fixed DCA. Any DCA hybrid dilutes V7's alpha. DCA only useful for
new monthly contributions that can't lump-sum into V7.
Conclusion: V7+VT36 remains SOTA across all tested frameworks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>