← Back to archive

1. The Feature Selection Problem

Machine learning models in finance face an acute feature selection challenge. With hundreds of potential predictors — technical indicators, fundamental ratios, macroeconomic variables, sentiment scores, volatility measures — the risk of overfitting increases with each additional feature. A gradient-boosted model with 200 input features can easily memorise noise in the training data, producing impressive in-sample performance that vanishes out of sample.

The standard approach in academic ML-for-finance papers (Gu, Kelly, and Xiu, 2020) is to include all available features and rely on the model’s internal regularisation to handle irrelevant ones. This works in very large datasets but fails for the sample sizes typical in systematic trading (2,000–5,000 daily observations). For these sample sizes, explicit feature selection before model training is essential.

2. Three Methods

2.1 Permutation Importance

The simplest approach: train the model on all features, then randomly shuffle each feature one at a time and measure the increase in prediction error. Features whose shuffling causes large error increases are important. The limitation is that permutation importance does not account for feature interactions: if two correlated features are both important, shuffling either one alone has little effect because the other compensates.

2.2 SHAP Values

SHAP (SHapley Additive exPlanations) values decompose each prediction into the contribution of each feature, using cooperative game theory. The key advantage over permutation importance is that SHAP correctly handles interactions and correlated features. The SHAP value for feature j on observation i tells you how much feature j contributed to pushing the prediction away from the average prediction. Aggregating |SHAP| values across all observations gives a global importance measure.

import shap
import lightgbm as lgb
import numpy as np

def shap_feature_importance(X_train, y_train, X_test):
    """
    Compute SHAP-based feature importance using LightGBM.
    Returns global importance ranking and interaction values.
    """
    model = lgb.LGBMRegressor(
        n_estimators=500, max_depth=4, learning_rate=0.05,
        subsample=0.8, colsample_bytree=0.6,
        reg_alpha=0.1, reg_lambda=1.0, random_state=42
    )
    model.fit(X_train, y_train)

    explainer = shap.TreeExplainer(model)
    shap_values = explainer.shap_values(X_test)

    # Global importance: mean |SHAP| per feature
    importance = np.abs(shap_values).mean(axis=0)
    ranking = np.argsort(-importance)

    # Top interaction pairs
    interaction_values = explainer.shap_interaction_values(X_test)

    return importance, ranking, interaction_values

2.3 Boruta Selection

Boruta (Kursa and Rudnicki, 2010) is a wrapper method that compares each real feature against “shadow” features — randomly shuffled copies of the original features. A feature is confirmed as important only if its importance consistently exceeds the maximum importance of any shadow feature across multiple iterations. This provides a formal statistical test for whether a feature carries genuine predictive information versus noise.

3. Experimental Setup

We construct 214 features across several categories: momentum/trend (48 features: various EWMA crossovers, ROC, ADX), mean reversion (31: z-scores, Bollinger deviations, RSI variants), volatility (42: realised vol, implied vol, GARCH forecasts, vol-of-vol), volume/liquidity (28: VWAP deviations, volume ratios, Amihud illiquidity), fundamental (37: earnings yield, book-to-market, dividend yield, sector-relative), and macro (28: yield curve slope, credit spreads, PMI, sentiment indices). The target is the next 5-day return of S&P 500 futures.

4. Results

MethodFeatures SelectedOOS R²OOS SharpeStability
All 214 features2140.8%0.31
Permutation (top 30)301.4%0.4762%
SHAP (top 30)301.7%0.5471%
Boruta (confirmed)231.9%0.5884%
Boruta + SHAP filter182.1%0.6389%

Table 1: OOS performance (2020–2023) by feature selection method. “Stability” is the Jaccard similarity of the selected feature set across 10 rolling training windows.

Boruta outperforms permutation importance on both prediction accuracy and stability. The combined Boruta + SHAP approach — using Boruta to select confirmed features, then using SHAP interaction values to remove redundant correlated pairs — produces the best result: OOS R² of 2.1% and Sharpe of 0.63 with only 18 features.

5. What the Selected Features Reveal

The 18 features selected by the combined method cluster into four groups: short-term reversal signals (5 features, dominated by 1-week return z-score and 5-day RSI), volatility regime indicators (4 features, led by the VIX term structure slope and 20-day realised vol), cross-asset signals (5 features, including yield curve slope, credit spread change, and copper-to-gold ratio), and liquidity measures (4 features, including Amihud illiquidity and volume relative to 20-day average). Notably, traditional momentum features — which dominate many academic studies — are not confirmed by Boruta, suggesting they do not carry incremental predictive information beyond what the reversal and volatility features already capture.

6. SHAP Interaction Effects

The most striking finding from SHAP analysis is the interaction between the VIX term structure and short-term reversal signals. When the VIX curve is in backwardation (short-term VIX above long-term, indicating acute stress), the short-term reversal signal becomes approximately 3× more predictive than in normal vol regimes. This interaction is invisible to linear models and to permutation importance, which treats features independently. It suggests that mean reversion is regime-dependent: reversals are more reliable after vol spikes because they reflect genuine overreaction, whereas “reversals” during calm markets are often just noise.

7. Conclusion

Feature selection is not optional for ML-based trading strategies with realistic sample sizes. Boruta provides the most rigorous statistical framework for distinguishing signal from noise. SHAP values complement Boruta by revealing interaction effects that inform both feature engineering and strategy intuition. In the worked example, the combination reduces a 214-feature set to 18, improves the illustrative out-of-sample R², and produces a feature set that is stable across most rolling windows — a critical requirement for a strategy that must be re-trained periodically without dramatic portfolio turnover.

References

  1. Gu, S., Kelly, B. and Xiu, D. (2020). "Empirical Asset Pricing via Machine Learning." Review of Financial Studies, 33(5), 2223–2273.
  2. Lundberg, S.M. and Lee, S.I. (2017). "A Unified Approach to Interpreting Model Predictions." NeurIPS Proceedings.
  3. Kursa, M.B. and Rudnicki, W.R. (2010). "Feature Selection with the Boruta Package." Journal of Statistical Software, 36(11).
  4. Chen, L., Pelger, M. and Zhu, J. (2024). "Deep Learning in Asset Pricing." Management Science, 70(2), 714–750.
  5. Freyberger, J., Neuhierl, A. and Weber, M. (2020). "Dissecting Characteristics Nonparametrically." Review of Financial Studies, 33(5), 2326–2377.