Every quant hits the same wall. You have hundreds of features that look predictive in isolation. Now you need to combine them into a single portfolio. This is a worked example of that problem: 576 features, 25 instruments, 5 asset classes, daily bars. What to select, how to combine, and where it quietly breaks.
1. The Problem
The investment universe is 25 instruments across 5 asset classes: equity index futures (ES, NQ, YM, FDAX, NKD), US bond futures (ZN, ZF, ZT, TN, US), commodities (CL, GC, SI, HG, ZW), G7 FX (EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CHF), and crypto (BTC, ETH, SOL, XRP, DOGE). The data spans 10 years of daily bars (2016–2026).
For each instrument, I compute 45 feature families spanning trend, mean reversion, volatility, volume, candle shape, support/resistance, and asymmetric signals. Each family is evaluated at 6 lookback periods (5, 10, 20, 50, 100, 200 bars), producing 576 features per symbol. The target is the volatility-adjusted 1-day forward return.
A raw feature value is continuous - you need a rule for when to trade. The simplest approach is quantile thresholds: go long when the feature is above its 80th percentile, short when below its 20th. Testing 5 threshold levels (10/20/30/40/50th percentile cutoffs) for each feature gives 576 features × 5 thresholds × 25 symbols ≈ 72,000 combinations.
The obvious approach: rank all 72,000 by Sharpe ratio over the historical data and trade the best ones. This is wrong, and for four reasons.
Selection bias. With 72,000 combinations, the best Sharpe will be high even if every signal is noise. You are not finding alpha - you are finding the right tail of a large distribution.
Stability across time and symbols. A feature that looks strong overall might work in one year and fail in the other nine, or work on one symbol and add noise on the rest. The selection metric needs to reflect how stable the signal is across time windows and across symbols - not just how large it is on average.
No out-of-sample if you use everything. If you use the entire history to pick the best features, there is no unseen data left to test them on. Every bar was already used in the selection. You need to hold out a test period, which means the selection can only use older data. This is the in-sample / out-of-sample split, and it is non-negotiable.
Which metric survives? The two obvious candidates are Sharpe ratio and information coefficient (IC). They measure different things, and one of them survives the split far better than the other.
2. Choosing a Selection Metric
Consider Sharpe first. I split the data into consecutive windows, ranked features by Sharpe in the first window, and checked whether that ranking predicted Sharpe in the next window:

The result: at 6 months (ρ = 0.05) and 18 months (ρ = 0.00), there is no relationship between a feature's Sharpe in one window and the next. Only at 5 years does a weak correlation appear (ρ = 0.29), but with only two non-overlapping windows that estimate is unreliable.
What if I average the top 20 instead of picking one? The decay is just as severe:

The top 20 features by first-half Sharpe averaged SR = 3.3 in the selection period and SR = 0.2 in the test period. 94% of the apparent performance disappeared. Selecting by |IC| instead of Sharpe and then measuring the combined Sharpe shows the same decay (93%). The problem is not the number of features - it is the gap between in-sample fit and out-of-sample reality at this search scale.
Ranking by Sharpe does not work, whether you pick the best 1, the best 10, or the best 50. But a different metric does work. Spearman IC (the rank correlation between a feature and subsequent returns) persists at all horizons:

At 6 months, consecutive-window IC correlation is ρ = 0.23 with 60% same-sign rate. At 18 months, ρ = 0.18. IC persists because it measures the rank relationship between feature and return, a structural property. Sharpe conflates signal strength with noise realization, which is why it fails on short windows.
A single feature with IC = 0.03 is almost useless on its own. But the point is not to trade one feature. The Lasso combines 10–20 partially independent weak signals into a single prediction. Each contributes a small edge; the combination produces a portfolio-level Sharpe that none of them could achieve alone. Weak IC is enough if you have breadth.
This gives us the first design choice: select features by IC, not by Sharpe. But it opens further questions - how to combine the selected features, how often to refit, whether to freeze the feature set or re-select periodically, and how to avoid leaking future data into the selection step.
If this kind of research is useful to you:
3. Method: IC Pre-Filter + Walk-Forward Lasso
Stage 1: IC pre-filter (once, on old data). For each asset class, compute Spearman IC between each feature and vol-adjusted returns, pooled across all 5 symbols. Keep the top N features by absolute IC. Freeze them permanently. The selection period is 2016-07 to 2021-06.
Stage 2: Walk-forward Lasso. For each symbol, fit LassoCV (L1-penalized linear regression with cross-validated regularization) on a rolling window of past data. The Lasso selects 2–8 features from the pre-filtered set and estimates their weights. Position = tanh(prediction × 1.5). OOS test starts at 2021-07-01.
The two stages operate on different timescales: IC selection is done once on frozen historical data (structural), Lasso weights adapt to the current regime (tactical). This follows the logic of two-stage variable selection procedures: screen first with a lenient criterion, then estimate on the screened set with a method tuned for prediction, not selection.
4. Feature Count, Lasso Lookback, and Per-AC Tuning
I swept 6 feature counts (10, 20, 30, 50, 100, 200) across 3 Lasso lookbacks (6, 12, 18 months). The features are selected once on 2016–2021 and frozen. OOS runs from 2021-07 to 2026-07.

Two findings:
6-month Lasso dominates. The left column (6m) is green across all feature counts. The 12m and 18m columns are mostly flat or negative. Shorter windows adapt faster to regime changes.
Feature count matters less than lookback. At 6m, SR ranges from 0.24 (50f) to 0.88 (10f). At 18m, nothing works. The Lasso lookback is the dominant parameter.
The bottom-right corner (200f, 18m) produces SR = 0.01 - effectively zero. The best uniform config (10f, 6m) achieves SR = 0.88. The Lasso lookback is by far the most important parameter.
Per-asset-class tuning. The uniform sweep treats all asset classes the same. But different asset classes respond to different feature counts. Commodities need 100 features (the Lasso benefits from a wider menu), while crypto and FX work best with 20. The Lasso lookback is universally 6 months.

Commodities: 100f, 6m Lasso, SR = 0.91
Bond Futures: 30f, 6m Lasso, SR = 0.95
FX: 20f, 6m Lasso, SR = 0.64
Equity Futures: 50f, 6m Lasso, SR = 0.58
Crypto: 20f, 6m Lasso, SR = 0.49
The combined per-AC optimized portfolio:

Portfolio SR = 1.08, positive every year including 2022 (SR = 0.5). The equal-weighted portfolio across 5 ACs with per-AC tuning produces consistent risk-adjusted returns with low cross-AC correlation.
Note: these are gross of transaction costs. At daily frequency with tanh sizing, turnover is moderate. A round-trip cost of ~10 bps would compress the portfolio Sharpe by roughly 20%, to approximately 0.85. See Caveats for details.

The annual breakdown shows genuine diversification: bonds were strong in 2022 when equities were flat, commodities led in 2025, FX strengthened in 2025–2026. No single AC drives the portfolio.
5. Why Re-Selection Fails
An intuitive alternative to frozen selection is rolling re-selection: every 6 months, re-compute IC on the most recent 5 years and pick the best features again. This adapts to regime changes. It should work better.
It does not.

Frozen wins every asset class. The Jaccard column shows why: only 41–64% of features survive from one re-selection window to the next. The features entering and leaving are the marginal ones near the IC cutoff. They carry almost no signal but they change the input space every 6 months, adding variance without adding predictive content. With frozen features the Lasso already refits weights each window - re-selection adds input churn on top of that, making consecutive models more different than they need to be.
The principle: separate selection from weighting. Freeze the feature set once on old data. Let the Lasso adapt weights each window. Re-selection conflates these two decisions into a single step, and the instability dominates.
This is a known result in statistics. Meinshausen and Bühlmann (2010) showed that the Lasso penalty optimal for variable selection (strong, sparse) is different from the penalty optimal for coefficient estimation (weaker, less shrinkage). Conflating the two in a single step hurts both. Belloni, Chernozhukov and Hansen (2014) formalized this as post-double-selection: perform selection and estimation in separate stages to avoid regularization bias. Freezing the feature set on old data is an extreme version of this separation - different data for each stage, not just a different penalty.
6. The Full-Sample Selection Trap
A common mistake looks perfectly rigorous: select the best features from your entire dataset, then run a walk-forward Lasso from the midpoint. The Lasso itself is causal - rolling window, no future data in weight estimation. But the result is contaminated.

The leakage is in the feature selection step. When you compute IC across the full sample to choose which features to keep, you are including the test period in the selection criterion. The features you hand to the Lasso were chosen because they had high IC on data that includes the OOS period.
To isolate this effect, I compared feature sets selected on the full dataset (2016–2026) versus features selected on 2016–2021 only, feeding both into the same walk-forward Lasso. The feature overlap between the two sets was surprisingly low: 0/10 for commodities and crypto, 3/10 for equities. Full-sample IC picks features that happened to work across the entire period - a different set from the features that were predictive before the test window.
The practical lesson: select features on data that strictly predates your first OOS bar. Freeze them. Any feature selection that touches OOS data - even indirectly through full-sample statistics - contaminates the walk-forward, and the contamination is invisible because the Lasso itself remains fully causal.
7. Conclusions
The key design choices, in order of importance:
Start OOS at the selection cutoff. The first OOS test bar must be at the feature selection cutoff. The Lasso trains on past data before that point - no gap needed between selection and testing.
Use a short Lasso window (6 months). Longer windows carry stale regime information. 6m beats 12m and 18m for every asset class.
Select features by IC on frozen historical data. Never use full-sample IC. The features with the highest full-sample IC are not the ones that work in walk-forward.
Tune feature count per asset class. Commodities need more features (100), crypto and FX need fewer (20). The Lasso handles the rest.
Combine, do not select. The Lasso combines many weak features into a single prediction. Individual features are too weak to trade alone (IC ≈ 0.02–0.05).
The combined portfolio achieves SR = 1.08 gross, likely 0.88–1.08 after accounting for per-AC selection bias. Bonds and commodities are the strongest asset classes; crypto is the weakest, consistent with its lowest OOS IC.
If you are starting from scratch: compute Spearman IC on your oldest data, freeze the top N features per asset class, fit a Lasso on a 6-month rolling window, and test on everything after the IC cutoff date. That is the entire pipeline.
Caveats. The per-AC feature counts were chosen on the test set, so SR = 1.08 is an upper bound. The uniform config (same settings for all ACs) achieves SR = 0.88 without any per-AC selection - the true performance likely sits between the two. These are gross returns with no transaction costs; at daily frequency costs will compress the Sharpe. All features are price-only.

Related Research
This post is part of a larger research programme on mid-frequency alpha. Related posts on Delphic Alpha:
Alpha Combinations, Part 1 — The maths of blending signals into a single prediction.
Alpha Combinations, Part 2 — From theory to practice: walk-forward Lasso on real data.
Simple Alpha Atlas — What actually works across markets on daily bars.
If you found this post valuable, share it with someone who builds systematic strategies:


Thanks for the writeup. Couple follow-ups.
- When you saw the trend was shorter rolling window size produces better results did you do a follow up and go to 4, 3, 1 months etc?
- Did you try giving any flavor of neural net ensemble the full set of features each asset and let it learn when to gate which and how many to use instead of keeping them static? It’s another layer of complexity to manage avoiding leaking and bias but I could see there potentially being a small edge gained over straight up stochastic.
I have more q’s but I’ll refrain