Machine Learning

Machine Learning for Stock Selection: Validation, Leakage, and Why Most Models Do Not Survive

Jeevan B A9 min readUpdated

Machine learning applied to stock selection means training a model to rank securities by expected future return, using features you supply, and holding the ones it ranks highest. The appeal is that a model can find interactions between variables that a linear factor screen cannot.

The reality is that most such models fail, and they fail for reasons that have little to do with the algorithm. They fail because the validation was wrong, because the data leaked, or because the edge they found was smaller than the cost of trading it. This article is mostly about those three things, because the modelling part is the easy part.

Start with quantitative analysis if the underlying testing discipline is new, since everything here builds on it.

What machine learning actually adds

A linear factor model says: rank stocks by some weighted combination of value, momentum and quality. Each feature contributes independently and in a straight line.

Machine learning relaxes both assumptions. A gradient-boosted tree can learn that momentum is predictive only when liquidity is above some threshold, or that cheapness helps in one volatility regime and hurts in another. Those are interactions and non-linearities, and they are genuinely present in markets.

The honest caveat is that this extra flexibility is exactly what makes the model dangerous. Financial data has a low signal-to-noise ratio, and a flexible model in a noisy dataset will fit the noise beautifully. A linear model can only be wrong in simple ways. A boosted tree can be wrong in extraordinarily specific ways that look, on your training data, exactly like insight.

Always fit the linear benchmark first. If the machine learning model cannot beat a regularised linear model out of sample, you have not found non-linearity, you have found a way to overfit more efficiently.

Validation is where most of these projects die

This is the single most important section, and it is the one most tutorials get wrong.

Standard k-fold cross-validation splits data randomly into folds, trains on some and tests on others. On a time series that is invalid, because some of your training data comes from after your test data. The model is being shown the future and then asked to predict the past, and it will do so impressively.

Two validation schemes on a timeline. Random k-fold cross-validation places a test block in the middle with training data on both sides, so the model trains on data from after the test period. Walk-forward validation always trains on data that precedes the test block. Random k-fold: invalid on time series train test train, but this is the future information flows backwards

Walk-forward: train only on the past test test test earlier later

The top scheme reports excellent scores and predicts nothing, because the training set contains information from after the test period. The bottom scheme mimics what actually happens in production: you only ever know the past. Expect walk-forward results to be substantially worse, because they are substantially more honest.

Walk-forward validation trains on a block of history, tests on the period immediately following it, then slides forward and repeats. The results are less impressive and they are the only ones that mean anything.

Two refinements matter in practice. Leave a gap between the end of training and the start of testing, because a target defined as a forward return overlaps the training window and leaks. And test across several distinct market regimes, since a model trained and validated entirely within one bull market has demonstrated only that the bull market continued.

Where leakage hides

Leakage is the use of information that was not available at decision time. It is rarely obvious and it is fatal.

Fundamentals belong to their publication date, not their period. A March quarter result is public weeks after March ends. Joining it to March dates means trading on numbers nobody had. This is the most common leak in Indian equity datasets and it produces spectacular backtests.

Index membership is known only in hindsight. Screening on today’s constituent list applies a filter that embeds years of survival. Build the universe as it stood on each historical date, which the NIFTY index methodology describes well enough to reconstruct.

Prices need corporate-action adjustment before anything else. Bonuses and splits create artificial gaps, and any feature computed on an unadjusted series inherits the error.

Normalisation across the full sample leaks. Standardising a feature using the mean and standard deviation of the entire history embeds future information into every past observation. Compute those statistics on the training window only.

Choosing the target, which decides everything downstream

The target variable is a modelling decision people make carelessly and then live with.

Predicting raw forward return means the model spends most of its capacity learning the market direction, which is the same for every stock and is not what you wanted. Predicting return relative to the index isolates the cross-sectional question of which stocks beat which, which is usually the actual question.

Predicting a binary label such as top-quintile membership is easier to model and discards magnitude, so a stock that beats by 40 percent counts the same as one beating by half a percent. Predicting continuous excess return keeps the magnitude and is noisier.

Neither is right in general. What matters is that the target matches how you will trade: if you intend to hold the top decile, train the model to rank, and evaluate it on ranking quality rather than on classification accuracy.

The features worth building

Group What it captures Note
Momentum and trend Persistence over three to twelve months The most robust effect, and the most crowded
Value Price relative to fundamentals Slow-moving; needs long horizons to express
Quality Profitability, stable earnings, low leverage Works over longer horizons than most backtests cover
Liquidity and microstructure Spread, turnover, depth Frequently important, and often a proxy for a risk you do not want
Volatility regime Realised volatility, dispersion Useful as a conditioning variable rather than a signal

That fourth row deserves attention. Liquidity features often rank highly in importance scores, and the reason is usually that illiquid stocks have higher returns because they are illiquid. The model has rediscovered a risk premium and labelled it alpha, and the strategy will not survive the slippage of actually trading those names.

Overfitting, and how to tell

Every hyper-parameter you tune uses up information in your sample. Test enough configurations and one will look excellent by chance alone.

The practical defences are unglamorous. Keep a final holdout period you examine exactly once, at the end, and accept its verdict. Prefer fewer features that you can justify economically over many that merely correlate. Watch the gap between training and validation performance, because a large gap is the definition of overfitting, and be suspicious of improvement that arrives only after extensive tuning.

The most useful single check is stability. Re-fit the model on slightly different periods and see whether its important features stay important. A model whose drivers reshuffle completely between windows has not learned anything durable, whatever its scores say.

It also helps to keep a record of every configuration you tested rather than only the one you kept. The count matters: a result significant at the five percent level means little as the twentieth thing you tried, because roughly one in twenty random configurations clears that bar by chance. Most people do not keep that count, which is precisely why the published result so often fails to repeat.

From model scores to an actual portfolio

A trained model outputs a number per stock. Converting those numbers into positions involves several decisions that affect returns more than the model does, and they are usually made by default rather than deliberately.

How many names to hold. Taking the top decile of a 200-stock universe gives 20 positions, which is roughly where idiosyncratic risk stops mattering. Taking the top five concentrates into the names where the model is most confident, and model confidence is not the same as being right. Concentration amplifies both the signal and the estimation error.

Whether to weight by score. Equal weighting across the selected names is robust and ignores information. Weighting by score uses more of the model’s output and gives the largest positions to the most extreme predictions, which are also the predictions most likely to be noise. Equal weighting wins more often than it should.

How often to rebalance. This is the decision that quietly determines whether the strategy is viable. Monthly rebalancing on a 20-stock portfolio can easily turn over a large fraction of holdings each period, and each turn pays brokerage, exchange fees, taxes and slippage. Compute the annual turnover, multiply by a realistic round-trip cost, and subtract it from the backtested return before deciding anything. Many models that appear to add value do so at a rate lower than the cost of harvesting it.

Constraints on the result. An unconstrained top decile can end up concentrated in one sector, which converts a stock-selection strategy into a sector bet without your having chosen one. Sector caps and position limits cost a little theoretical return and remove a large amount of unintended exposure.

None of these are modelling questions, and all of them are decided before a single position is opened.

When the answer is not machine learning

Complexity has to earn its place, and often it does not.

If the model cannot beat a linear factor model after costs, the extra machinery is adding risk of error without adding return. If the strategy demands high turnover to express its edge, transaction costs will consume it, and this is worth calculating early rather than discovering late. And if the dataset is small, and Indian equity history with clean fundamentals is not long, a flexible model has too much freedom relative to the evidence available.

For portfolio-level implementation of whatever signal survives, see portfolio construction, and for sizing it responsibly, risk management. For the analytics primitives, quantflow-finance is the open-source library I maintain.

The algorithm is the least interesting part of this problem. Data hygiene and honest validation decide it, and they decide it long before the model is trained. Spend your time there and the choice of model becomes almost incidental.