PlusEVData/investing

What's predictive in this universe

Russell 3000 cross-section, 2018-2026, 500 symbols ร— 5+ years of point-in-time fundamentals. Of 944 feature-horizon combinations tested, only 23 survived the bullshit filter. They cluster into 6 themes. The rest is noise.

The 6 themes that survived

Theme 1
Size premium
Smaller market caps outperform larger. IC at 252d: โˆ’19.6% on mcap_pit. Hit 100%.
mcap_pit ยท ev_pit ยท shares_diluted_*
equity ยท book_value ยท raw net_income
Fama-French SMB. Real, well-documented since 1981.
Theme 2
Value premium
Cheaper outperforms expensive. IC at 252d: +14.2% on sales_yield_pit.
ps_ttm_pit ยท pe_ttm_pit
sales_yield_pit ยท book_yield_pit
Fama-French HML. P/S works better than P/E in our era.
Theme 3
Vol risk-premium
High annualised vol โ†’ bigger 252d return. IC: +19.6% on vol_252d.
vol_252d ยท vol_90d
CAPM-style risk premium. Not a stock-picking edge unless paired.
Theme 4 โ€” counterintuitive
Quality penalty
High-margin / consistently-profitable stocks underperform. IC: โˆ’10.2% on net_margin_pit.
net_margin_pit ยท gross_margin_pit
op_margin_pit ยท cfo_q_pct_quarters_positive_8q
Quality is priced rich โ€” no value premium left.
Theme 5 โ€” counterintuitive
Cash penalty
More cash hoard โ†’ smaller return. IC: โˆ’5.5% on cash.
cash ยท cash_yoy_growth (weak)
Mature, low-growth signal.
Theme 6
Momentum / 52-week
Far above 52-week low โ†’ bigger return. IC: +11.7% on dist_52w_low.
dist_52w_low ยท wq_alpha042
(most other momentum is NOISE)
Jegadeesh-Titman momentum.

โšช What's NOT predictive (out of 800 noise features)

Many things people commonly think predict returns are statistically indistinguishable from random in our 5-year, 500-symbol panel:

Technical indicators
  • RSI (2, 5, 7, 14, 21, 30) โ€” all noise
  • MACD, MACD signal, MACD histogram
  • Stochastic K and D
  • Bollinger band width, %B
  • Most chart patterns (doji, hammer, engulfing, inside/outside bar)
  • Gap percentage, streak features
WorldQuant alphas
  • 25 of 29 wq_alpha* features failed
  • Only 042 (real signal) and 032 (real, smaller) survived
  • WQ001-019, 026, 033-035, 037-038, 040-053 โ€” all noise
  • (Some are degenerate cross-sections โ€” see "suspect" tag)
Growth rates
  • Revenue YoY/QoQ growth โ€” noise
  • Earnings YoY/QoQ growth โ€” noise
  • Asset growth, liabilities growth โ€” noise
  • Equity / book value growth โ€” noise
  • The LEVELS of certain ratios predict returns; the GROWTH of fundamentals doesn't
Quality metrics (individually)
  • Piotroski F-score sub-components โ€” most fail
  • Beneish M-score โ€” noise individually
  • Sloan accruals โ€” noise individually
  • (They may help as filters but not as ranking signals)
Short-term momentum
  • Returns 5d, 21d, 63d โ€” noise
  • Sortino at short horizons โ€” noise
  • Volume features โ€” mostly noise
  • Only mom_12_1 and dist_52w_low work
Most "factor" composites
  • Magic Formula composite โ€” weak
  • Piotroski composite โ€” weak
  • Equal-weighted multi-factor โ€” weak
  • (Better to weight by IC than equal-weight)

Caveat: "noise" means individually below our threshold. A feature can fail individually and still help in a multi-factor composite. The bullshit filter is for "is this a standalone signal."

๐Ÿ“ Strategy implications

A composite that bets on the 6 surviving themes:

  1. Smallest cap within universe (exclude micro-cap noise: market cap โ‰ฅ $300M)
  2. Cheapest by P/S (P/S < 3.0)
  3. Sub-median margin โ€” avoid quality trap (operating margin < 30%)
  4. Above 52-week low by โ‰ฅ20% (momentum gate to avoid value-traps)
  5. Quarterly rebalance, equal-weight, 25 names

This is the ic_validated_value_size strategy. Backtest 2022-2026: Sharpe +1.42, Sortino +1.93, CAGR +52.4%, MaxDD โˆ’35%, random-baseline 100th percentile, p < 0.001.

๐Ÿ”ฌ Sector-neutral test โ€” true alpha vs sector bet

A signal can have high IC because it accidentally bets on the right sector. To test this we subtract the per-(date, sector) mean from both feature and forward return, then recompute IC. Sector-neutral IC = pure cross-sectional alpha.

FeatureRaw ICSector-neutral ICRetainedVerdict
mcap_pit (size)-19.60%-7.58%39%Mostly a sector bet
sales_yield_pit (low P/S)+14.33%+12.75%89%Real alpha
earnings_yield_pit (low P/E)-0.30%+0.10%35%Was already noise
net_margin_pit (quality penalty)-10.23%-7.74%76%Mostly real alpha
vol_252d (vol risk-premium)+19.69%+17.40%88%Real alpha
dist_52w_low (uptrend / momentum)+11.79%+11.93%101%Pure cross-section alpha
wq_alpha042 (WorldQuant ฮฑ)+11.15%+9.48%85%Real alpha

Headline: the apparent size effect in our universe is 61% sector exposure (financials skew small, tech skews large; size IC partially measures sector bet). The true cross-sectional alpha signals are dist_52w_low, vol_252d, sales_yield_pit and net_margin_pit (negative). They should be the spine of any composite strategy.

โš  Universe coverage caveat

Our point-in-time fundamentals universe covers 500 names with median market cap ~$45B โ€” i.e. roughly the S&P 500 plus some recent IPOs. So the "size effect" reported above is $15B mid-caps outperforming $200B mega-caps within the S&P 500, NOT small-cap (< $2B) outperformance. The Fama-French SMB size premium is well-documented to be much stronger in true small-caps; we cannot measure that directly with this data.

What this means in practice: the IC-validated strategies on /strategies filter for $5B-$50B (smallest within our coverage). To target true small-caps we'd need to ingest EDGAR XBRL facts for the rest of Russell 3000 โ€” that's a roadmap item.

Browse: full IC table ยท strategy library ยท lessons & methodology ยท backtester

โš– Regime test โ€” composite vs leader vs benchmark

Tests whether each strategy works across regimes. Composite_6sig = sector-neutral IR-weighted score from the 6 features that survived every gate. Leader = low_atr ร— high_dist_52w_low. Mega-cap = top-20 by market cap (signal-free benchmark). Top-20 quarterly rebalance, 12bps cost.

StrategyRegime SharpeSortinoCAGRMaxDDSkewRebals

Headline finding: the composite_6sig works in BOTH regimes (pre-shock 2021 Sharpe +1.23, post-shock 2022-2026 Sharpe +1.62). The leader produces zero valid pre-shock holdings (its 52-week feature needs warmup data the panel doesn't have) โ€” it is post-2022-conditional. Use the composite as primary; use the leader as a tactical post-shock overlay.

Source: scripts/composite_regime_test.py ยท See strategies for live signals ยท Full report at reports/COMPOSITE_REGIME_TEST.md.

๐Ÿญ Industry-relative features โ€” comparing each company to its peers

For each feature, we tested 4 variants: abs (raw), vs_ind (excess over industry median), ind_z (industry z-score), ind_pct (industry percentile rank). Tested on 21 features ร— 110 industries ร— 3 horizons. 12 of 21 features improve as industry-relative. Cheapness ratios benefit most (P/B vs peers > absolute P/B).

FeatureBest variantMean ICt_NWIR_eff

Composite_industry_relative โ€” combining 19 winning variants: . Comparable to per-sector composite (1.96 Sharpe) but with finer-grained risk control. Per-sector is slightly higher Sharpe because 11 sectors have more statistical power than 110 industries.

๐Ÿ“Š Bootstrap 95% confidence intervals

Block-bootstrap (21d blocks, 1000 reps) of daily returns. Gives a confidence range on Sharpe / Sortino / MaxDD. P(Sharpe > 0) = probability of positive Sharpe under the bootstrap distribution.

Strategy Point SharpeSharpe 95% CI Point MaxDDMaxDD 95% CI P(Sharpe>0)

composite_flat / Y 95% Sharpe CI [+1.00, +2.54] โ€” the lower bound is exactly +1.00, meaning we can be 95% confident the strategy's true Sharpe is at least 1.0. P(Sharpe>0) is 100% across all three composites.

๐Ÿ”’ Holdout test โ€” combo lift held up out-of-sample

Reserved last 12 months (2025-05-04 โ†’ 2026-04-30) as holdout. Refit MV-LedoitWolf weights using ONLY in-sample data, then evaluated those weights on both windows.

WindowStrategySharpeSortinoCAGRMaxDDDays

Verdict: โœ… in-sample combo lift +0.22 Sharpe; holdout combo lift +0.54 โ€” the diversification benefit didn't degrade out-of-sample. Equal-weight (no fitting at all) gave nearly identical holdout Sharpe (3.52) to MV combo, suggesting the MV optimizer isn't overfitting โ€” it just nudges toward what 1/N already does.

Caveats: 245-day holdout is small; 2025-26 was a strong bull market โ€” all long strategies look great. Per single-shot holdout protocol, this read has now burnt the holdout for this strategy. To roll forward we either (a) deploy and let the next 12 months of live trading become the new holdout, or (b) keep researching but never use 2025-2026 data for fitting again.

Source: scripts/multi_strategy_holdout.py + HOLDOUT_PROTOCOL.md

๐Ÿ“‰ Capacity & slippage โ€” strategy doesn't scale much past $50M

Square-root market impact model (Almgren-Chriss / Kissell): slippage = K ร— ฯƒ ร— โˆš(Q/ADV). Conservative K=1.0. The leader's actual basket today is small-mid cap names (e.g. SNDK $1.2B, BE small) with ADV $20-50M. A $50M AUM means 5-10% of ADV per position โ†’ punishing slippage.

AUMOne-way slippageAnnual cost (8 turns/yr)% of 53% CAGR

Practical capacity: roughly $10-50M with conservative K=1.0; possibly $50-200M with realistic K=0.2 (typical for liquid large-caps but our basket isn't large-cap). Past that, alpha is eaten by impact costs.

Implication: this is a low-capacity strategy. Good for personal capital deployment, doesn't scale to institutional size without changes (larger universe, slower turnover, or moving to truly large-cap names with worse expected alpha). The reversal stream in our combo is even less scalable (daily turnover).

Source: scripts/capacity_and_slippage.py

๐Ÿ“ Deflated Sharpe Ratio โ€” accounting for selection bias

We tested ~944 features ร— 4 horizons ร— multiple variants. Picking the best inflates observed Sharpe. Deflated Sharpe (Lรณpez de Prado 2014) computes the probability the result isn't selection-bias artifact, given N independent trials.

VariantN trialsSharpe obsSharpe nullz-scoreDSR%

Verdict: at the conservative N=5000 trials assumption, leader+gate has DSR = 93.2% ("likely real alpha"). Even at N=10,000, DSR stays above 90%. Raw leader without gate drops to 77% โ€” the gate is what makes the strategy DSR-significant. Null Sharpe expected from picking best of 5000 random strategies on this sample = 1.38; we're +0.56 above null.

Source: scripts/deflated_sharpe.py

๐Ÿ”€ Multi-strategy combo โ€” Fundamental Law in practice

Built 3 new alpha streams to test diversification: short-horizon reversal (3-day), quality (gross-profitability + cash-flow yield), and 12-1 momentum. Goal: find UNCORRELATED streams to lift combined Sharpe via mean-variance optimization with Ledoit-Wolf shrunk covariance.

Standalone Sharpes + correlations with leader:

StrategySharpeSortinoCAGRMaxDDฯ vs leader
leader+gate1.942.9453%-19.6%-
reversal_3d (daily, 5bps)1.011.4934%-59%+0.008
quality (GP/A + CFO/MC)1.051.5224%-33%+0.449
momentum 12-11.361.9449%-45%+0.637

Key finding: only reversal is genuinely uncorrelated (ฯ = +0.008). Quality and momentum overlap with the leader (they too prefer big stable uptrending names, just via different metrics). The MV optimizer sees this and downweights them: leader 62%, reversal 25%, quality 7%, momentum 6%.

Combo results (4-way, mean-variance Ledoit-Wolf shrinkage):

VariantSharpeSortinoCAGRMaxDDVol

Headline: MV-LedoitWolf combo lifts Sharpe from 1.94 โ†’ 2.20 (+0.26), the Fundamental Law of Active Management in action. The trade-off: MaxDD widens from -19.6% to -27% because reversal's standalone -59% MaxDD bleeds through at 25% weight. Calmar holds steady (~1.78 vs 2.72 standalone-leader); Sortino jumps from 2.94 to 3.34.

Where the lift came from: reversal alone. Quality and momentum gave essentially zero incremental Sharpe (combo with just leader+reversal is also Sharpe 2.18-2.20). For more lift we'd need genuinely orthogonal alpha โ€” options-skew, cross-asset trend, or alternative data, none of which yfinance serves historically. Free-data ceiling is approximately here.

Source: scripts/strategy_reversal.py, scripts/strategy_quality.py, scripts/strategy_momentum.py, scripts/multi_strategy_combo.py

โœ… Extended 7-year backtest (2019-2026): honest numbers

Earlier docs claimed "8-year backtest" but the panel only started 2021. May 4 v10: rebuilt panel from 2018-01-02 using a lean script (only the 6 features we use). Now have 1812 trading days (7.2 years) of usable history including 2019 bull, 2020 covid crash, and 2021-22 rate shock.

VariantSharpeSortinoCAGRMaxDDCalmar
Raw leader1.662.4363%-46%1.39
+SPY 100d gate1.942.9453%-19.6%2.72
+gate+vt081.923.1920%-10.0%2.02
+gate+sortino121.922.9950%-20.1%2.49

Per-regime breakdown (raw leader): 2019 bull Sharpe 2.18 / MaxDD -8% โ€ข 2020 covid Sharpe 1.31 / MaxDD -46% โ€ข 2021-22 rate shock Sharpe 0.23 / MaxDD -35% โ€ข 2023-26 rebound Sharpe 2.53.

Gate is heroic in 2020 covid: raw Sharpe 1.31 โ†’ with gate 2.50; raw MaxDD -46% โ†’ with gate -13%. The gate exits the day SPY crosses below its 100d MA, sidestepping the bulk of crash. But gate is a drag in 2019 stable bull (Sharpe 2.18 โ†’ 0.31; too many false exits). Net over 7 years, gate adds +0.28 Sharpe and halves MaxDD.

Source: scripts/leader_subperiod_robustness.py + scripts/sortino_target_gated_leader.py on rebuilt 7y panel.

๐Ÿ” Survivorship-bias audit: bias smaller than feared, but not zero

Today's universe (current IWV, 1490 names) excludes companies that delisted before 2026. Tested by restricting universe to symbols that existed AND had data on 2018-01-01 (1263 names).

SubperiodFull panel (today's IWV)Pre-2018 existing onlyฮ” Sharpe
FULL 2019-20261.661.58-0.08
2019 bull2.182.180.00
2020 covid1.311.24-0.07
2021-22 rate shock0.230.35+0.12
2023-26 rebound2.532.40-0.13

Index-churn bias is small (0.08 Sharpe drag). The leader picks established large-caps which churn less in IWV than small-caps would.

Unmeasurable risk: 74 truly delisted S&P 500 names (2018-2024) are missing from BOTH variants โ€” including SIVB, FRC, SBNY (failed banks 2023), ATVI/TWTR/PXD (M&A). yfinance no longer serves these tickers. The leader's selection criteria (low atr ร— high dist_52w_low) would specifically have picked SIVB-style names โ€” calm and uptrending right up until they collapsed. The 7y Sharpe of 1.66 is a high estimate; true Sharpe with delisted names included is unknown but likely lower.

Source: scripts/survivorship_audit.py + scripts/find_delisted_names.py

โš–๏ธ Sortino-target overlay โ€” beats vol-target

Tested vol-target (scales by total realized vol) vs sortino-target (scales by downside deviation only) on the gated leader. Sortino-target at 12% wins: preserves upside spikes that vol-target clips, keeps CAGR higher at similar Sharpe, and gives better Calmar.

VariantSharpeSortinoCAGRMaxDDCalmarVol

Why sortino > vol-target: a 5% up day looks like "increased risk" to vol-target โ†’ de-leverages going forward. Sortino-target only de-levers on negative shocks. Result: keeps upside, dampens drawdowns, better Calmar (2.84 vs 2.24 for vt15).

Source: scripts/sortino_target_gated_leader.py

๐Ÿ” Gate universality โ€” gate is signal-specific, not universal

Tested SPY>100d gate on 8 different base strategies. The gate isn't universal โ€” its lift correlates with whether the strategy picks volatile stocks. Strategies involving atr_14 or range_true get +0.27-0.30 Sharpe lift. dist_52w_low-driven strategies get only +0.05-0.08 (already self-filter for trending stocks).

StrategyNo gate Sharpe+Gate SharpeLiftVolNo gate MaxDDGate MaxDD

Mechanism revealed: the gate works specifically when the strategy picks stocks that get hammered in selloffs. atr_14 (low-volatility preference) means the basket is calm in normal markets but those calm stocks crash hard in shocks โ†’ gate exits cleanly. dist_52w_low already tilts toward stocks in established uptrends โ†’ less benefit from regime exit (those tend to hold up better anyway).

Source: scripts/gate_universality.py

๐Ÿ”ฌ Robustness sweep โ€” gate works in EVERY config

Tested 45 configurations: rebal_freq M/Q/Y ร— target_n 10/15/20/30/50 ร— cost 8/12/20bps. The gate adds Sharpe in 100% of configs (median lift +0.30, range [+0.12, +0.35]). 62% of configs hit Sharpe > 1.8. This isn't a curve-fit โ€” it's a real signal that survives every reasonable parameterization.

FreqnCost No gate+GateLiftCAGRMaxDD

Top finding: Q ร— n=10 ร— 8bps gives the highest Sharpe (1.99). Q ร— n=20 (our previous "best", Sharpe 1.96) is barely behind. The strategy is robust across the entire parameter neighbourhood.

Top 15 of 45 configs shown. Source: scripts/robustness_sweep_gate.py

๐ŸŒ Cross-asset gates โ€” none beat SPY 100d alone

Tested 12 alternative regime filters: yield curve inversion, HYG/IEI credit ratio, USD trend (UUP), VIX percentile. Useful negative result: spy>100d alone (Sharpe 1.96) is the best โ€” adding cross-asset filters either dilutes Sharpe (too restrictive) or doesn't help. Yield curve never inverted in the window. USD trend / VIX percentile actively hurt as gates.

GateSharpeSortinoCAGRMaxDDIn market

Source: scripts/cross_asset_gates.py

โš  Live macro gate signal

The leader_spy_100d_gate strategy is currently in CASH (signal = RED).

SPY is below its 100-day moving average as of . The strategy holds zero positions until SPY recovers above the 100d MA. This is exactly the gate's purpose โ€” it sat out the 2020 covid crash and 2022 rate shock the same way.

Strategy is currently LONG (signal = GREEN). SPY is above its 100d MA.

Auto-refreshes every page load. Source: SPY adj_close vs 100d rolling-mean MA.

๐Ÿ›ก Stack: SPY>100d gate + vol-target overlay

Does stacking the gate with vol-target push Sharpe past 1.96? Answer: no โ€” gate alone is already optimal Sharpe. Vol-target on top of the gate scales leverage down: lower CAGR + lower MaxDD, same Sharpe. Pick based on volatility tolerance.

VariantSharpeSortinoCAGRMaxDDVolIn market

Two production picks (same Sharpe 1.96, different risk profile):

  • Aggressive: leader + spy>100d gate โ†’ CAGR 54%, MaxDD -19.6%, vol 16%
  • Defensive: leader + spy>100d gate + vt08 stack โ†’ CAGR 20%, MaxDD only -10%, vol 6%

Note: gate-first then vt > vt-first then gate (1.96 vs 1.82 Sharpe). Sequence matters. Source: scripts/stack_gate_voltarget.py

๐Ÿ†๐Ÿ†๐Ÿ† SPY trend-gate sensitivity sweep โ€” robust gate found

Tested 10 SPY trend-gate variants (single MA at 50/100/150/200/300d + dual gates) on both leader and flat composite. Single 100d MA gate is the new winner: Sharpe 1.96 (vs leader alone 1.66, +0.30 lift). All gates in 100-200d range give Sharpe โ‰ฅ 1.80 โ€” the gate is ROBUST, not lucky on a specific parameterization.

BaseGate SharpeSortinoCAGRMaxDDIn market

Key takeaways:

  • Leader benefits MUCH more from gates than flat composite (+0.30 Sharpe vs +0.13). The leader's high-vol picks are hit harder in selloffs, so regime filtering helps more.
  • 100d MA single gate is optimal: less restrictive than 200d (more upside captured) but less choppy than 50d (fewer false signals). Sweet spot.
  • Dual gates aren't needed โ€” the 50/200 dual we tried earlier (Sharpe 1.84) is dominated by single 100d (1.96).
  • Robustness: 5 of 10 leader-gate variants give Sharpe โ‰ฅ 1.84. The gate isn't a curve-fit โ€” it's a real regime signal.

Source: scripts/macro_gate_sensitivity.py

๐Ÿ†๐Ÿ†๐Ÿ† Macro overlay โ€” NEW BEST (Sharpe 1.84)

Apply a SPY trend gate or VIX gate on top of the leader strategy: when conditions are bad, sit in cash. No fitting โ€” these are textbook regime filters. SPY dual-trend gate (50d AND 200d) lifts Sharpe from 1.66 โ†’ 1.84 (+0.18) while spending 32% of the time in cash, avoiding the worst regimes.

VariantSharpeSortinoCAGRMaxDDVolIn market

Two clear winners:

  • ๐Ÿ† Leader + SPY dual-trend gate: Sharpe 1.84 (highest), CAGR 44%, MaxDD -22%. The simplest rule: only hold when SPY is in clear uptrend on both 50d AND 200d MAs.
  • ๐Ÿฅˆ Leader + 8% vol-target + VIX<30 gate: Sharpe 1.83, MaxDD only -12.4% โ€” most defensive variant.

Source: scripts/macro_overlay.py

๐Ÿ†๐Ÿ† Leader + vol-target & combo experiments โ€” NEW BEST FOUND

Vol-target overlay on the leader strategy + 50/50 combo with flat composite. Same trick that hurt per-sector composite IMPROVES the leader. Leader + ฯƒ*=8% vol-target โ†’ Sharpe 1.76 (HIGHER than unleveraged leader's 1.65) AND MaxDD just -15% (vs leader's -46%).

VariantSharpeSortinoCAGRMaxDDVolSkew

Why vol-target works on leader (but hurt the per-sector composite): Leader has fixed weights (no in-sample fit), so vol-target just rescales good days and bad days proportionally โ†’ the Sharpe-improving Kelly-style behaviour kicks in. Per-sector composite had unstable weights between quarters; vol-targeting unstable returns just amplified the noise.

The 50/50 combo finding: leader and flat composite are 90.7% correlated โ€” they pick similar names. Combining gives Sharpe 1.54 (between the two) but doesn't improve risk-adjusted return meaningfully. The diversifier we hoped for isn't there.

Source: scripts/leader_combo_voltarget.py

๐Ÿ† Leader strategy walk-forward โ€” verified honest #1

The leader (low_atr ร— high_dist_52w_low) uses fixed sort weights โ€” nothing to overfit. Walk-forward on 2019-2026: Sharpe +1.66 (vs initial in-sample 1.88, only -12% deflation โ€” much better than per-sector composite's -57% deflation).

Sharpe
Sortino
CAGR
MaxDD
Total return (8y)
Quarters tested
Positive quarters
Median quarterly return
Worst quarter

This is the honest #1 production strategy. Beats the flat composite (Sharpe 1.28) by +0.38, with a similar drawdown. Use composite_5sig_yearly (flat) as a complement / hedge, since they hit different regimes.

Source: scripts/walkforward_leader.py

โš  Walk-forward โ€” the honest test that broke the per-sector claim

The 8-year regime stress test fit per-sector weights ONCE on the full panel, then "applied" them quarter-by-quarter โ€” a subtle leak. True walk-forward refits weights each quarter using ONLY data prior to that rebal.

StrategySharpe (in-sample)Sharpe (walk-forward)ฮ”Verdict
composite_flat (no fit) 1.28 1.28 0.00 No overfit possible
composite_per_sector 1.61 0.69 -0.92 Mostly in-sample fit

Verdict: use composite_5sig_yearly (flat) as the honest production strategy. Per-sector composite's quarterly weight refits cause 490% annualised vol โ€” weights swing wildly between quarters because each refit only uses ~1-7 years of training data. The "+0.33 Sharpe lift" we celebrated yesterday was almost entirely overfitting to recent data.

Source: scripts/walkforward_per_sector.py. 30 quarterly refits 2019-Q1 โ†’ 2026-Q2. This is the value of walk-forward testing โ€” it catches overfitting that even careful 8-year stress tests miss.

๐Ÿ›ก Multi-cycle stress test on 2018-2026 panel

The honest test: do per-sector weights generalise out-of-sample, or are they fit to 2021-2026? Answer: they generalise โ€” Sharpe 1.61 over 8 years (+0.33 over flat composite 1.28), but the per-sector composite is more leveraged so it gets bigger drawdowns in selloffs. Vol-target ฯƒ*=15% is the institutional-grade overlay โ€” caps the drawdown without much Sharpe loss.

RegimeStrategy SharpeCAGRMaxDDTotal ret

Reading the verdict. 2018-Q4 selloff: per-sector loses MORE than flat (-13.9% vs -11.7%) because high-vol picks amplify in down markets. 2019 bull / 2020-21 recovery / 2023-26 rebound: per-sector wins by big margins. 2022 rate shock: per-sector + voltarget loses just -4.3% vs mega-cap -8% AND flat -25.8%.

Honest summary: the per-sector composite is essentially a leveraged bull-market amplifier. The vol-target variant is the only one that doesn't blow up in 2018-Q4 / 2020 covid / 2022 rate shock all at once.

๐Ÿ† Best-of-everything combo (full window)

Combine all 3 improvements: per-sector weights ร— annual rebal ร— vol-target overlay. Source: scripts/best_of_combo.py. The best risk-adjusted strategy beats the original by Sharpe 1.31 โ†’ 2.03 AND MaxDD -55% โ†’ -13%.

ConfigSharpeSortinoCalmarCAGRMaxDDVolSkew

Three picks for different risk appetites in the full window:

  • Pure return: per-sector / Y โ†’ Sharpe 1.96, CAGR 91%, MaxDD -34%
  • Best Sharpe: per-sector / Y / ฯƒ*=15% โ†’ Sharpe 2.03, CAGR 38%, MaxDD -13%
  • Capital preservation: per-sector / Y / ฯƒ*=8% โ†’ Sharpe 1.97, CAGR 21%, MaxDD only -8.1%

Caveat: per-sector weights are fit in-sample on 2021-2026 panel. True OOS test pending the 2018-extended panel rebuild (running on VPS).

๐Ÿš€ Per-sector-weighted composite โ€” biggest single Sharpe lift

Uses sector-specific IR_eff weights instead of pooled global weights. Sign-aware: range_true gets positive weight in Materials (where it's +1.6% IC) and negative in Tech (-23.7% IC). Same panel, same rebalance, just smarter weighting. +0.49 Sharpe lift over flat composite.

RegimeScoreSharpeSortinoCAGRMaxDDCalmar

Pre-shock 2021: flat 0.71 โ†’ per-sector 1.39 (+0.68 lift). Post-shock 2022-2026: flat 1.57 โ†’ per-sector 2.03 (+0.46 lift). Full: flat 1.47 โ†’ per-sector 1.96 (+0.49 lift, CAGR 61% โ†’ 91%). Caveat: per-sector weights fit on same data โ€” true OOS test pending the 2018 panel rebuild.

โฑ Rebalance frequency โ€” annual is optimal

Same composite_5sig basket, different rebalance cadence. Cost = 12bps ร— 2 ร— turnover at each rebal. Source: scripts/rebalance_freq_sweep.py. Annual gives best Sharpe AND lowest cost โ€” slow signal decay (most features are 252d horizon).

RegimeFreqSharpeCAGRMaxDDAvg turnoverEst cost/yr

Best Sharpe-after-cost is annual rebalance (Sharpe 1.47 in full window, only 13bps/yr cost). Weekly looks high-Sharpe but pays 358bps/yr in costs; quarterly is over-trading the slow signals. New strategy: composite_5sig_yearly on the strategies page.

โš™ Vol-target overlay on composite_5sig

Apply 60-day-realised-vol leverage to the composite portfolio. Lev_t = min(2.0, ฯƒ* / ฯƒ_60(t-1)). Source: scripts/vol_target_composite.py. Lifts Sharpe +0.15 and cuts MaxDD by 65%.

RegimeTarget ฯƒSharpeSortinoCAGRMaxDDVol realisedSkew

Sweet spot is ฯƒ*=12-15% in the full window โ€” Sharpe 1.46 (vs baseline 1.31) with MaxDD just -21% (vs baseline -55%). In post-shock-only the overlay slightly hurts Sharpe but still cuts MaxDD by half. Recommendation: run composite_5sig with vol-target overlay set to 12-15% for live deployment.

๐ŸŒ Per-sector IC โ€” signals reverse sign by sector

Computed h=252 IC restricted to each sector. Massive heterogeneity. range_true is +6% IC pooled but negative in 8 of 11 sectors (catastrophically -23.7% in Tech). The flat composite uses pooled weights; per-sector weights are demonstrably better.

Sector dist_52w_lowvol_252dgap_abswq_alpha042range_true

Strongest signal per sector: Tech / Cons. Disc. โ†’ wq_alpha042; Industrials / Real Estate / Materials / Utilities / Comms โ†’ vol_252d; Financials / Cons. Staples / Health Care โ†’ range_true (negative direction); Energy โ†’ wq_alpha042. This argues for a per-sector composite โ€” being computed once panel extension to 2018 lands.

๐Ÿ“Š All-strategies regime breakdown

Every curated strategy through the same pre/post-shock split. Robust = positive Sharpe in BOTH regimes. Strategies with pre-shock errors typically need 52-week feature warmup that doesn't exist in 2021 data.

Strategy Pre SharpePost Sharpe Pre CAGRPost CAGR Avg SharpeRegime-robust?

Source: scripts/all_strategies_regime_test.py. Refresh page to pick up newly-completed entries.

๐Ÿ“ฆ Today's IC-validated basket (live from screener)

Top picks right now from the ic_sector_neutral_pure_alpha strategy. Liquid mid/large-cap, P/S < 4, sub-30%-margin, >20% above 52w low. Sorted by combined rank.

#SymNameSector P/SMCapOpMgn52wLow

Note: this is a research basket, not financial advice. Always verify the underlying thesis on each name. Consider sizing, sector concentration, and your own risk budget.