Rank Targets and Cross-Sectional Normalisation
Converting each period's raw returns into ranks (or standardized z-scores) across the whole universe before training, so a model learns which stocks did relatively well or badly rather than getting distracted by market-wide moves that lift or sink everything at once.
Prerequisites: Choosing the Prediction Target: Return, Rank or Direction
In a month when the entire market rises 10%, almost every stock posts a positive raw return — good, bad, and mediocre companies alike get carried up together. A model trained to predict raw returns in that month is mostly learning to say "positive," which is true but useless: it tells a long-short stock-picker nothing about which of those stocks to actually favor over the others. What a long-short strategy needs isn't "will this stock go up," it's "will this stock do better or worse than its peers this period" — and that's a cross-sectional question, answered by comparing stocks to each other within the same period, not to some fixed absolute bar.
Turning returns into ranks
Rank-based cross-sectional normalisation replaces each stock's raw return with its rank (or percentile) among all stocks in the universe for that same period. If there are stocks in the universe on a given date, the stock with the highest return gets rank 1 (or percentile 100%), the lowest gets rank (or percentile close to 0%), and everything else falls in between. Some pipelines take this further into a full z-score: subtract the cross-sectional mean return that period and divide by the cross-sectional standard deviation, which keeps a magnitude sense (how far above or below "typical this period" a stock was) while still fully removing the common, market-wide component, since a shift that hits every stock equally cancels out in both the mean-subtraction and (largely) in relative spacing.
In plain English: instead of asking "did this stock go up," the label now asks "did this stock go up more than most other stocks did that same period" — a question whose answer doesn't automatically flip to "yes for everyone" just because the whole market happened to rally that month.
Worked example: a rally month, ranked
Suppose five stocks return in a month when the whole market is up roughly 10% on average. As raw returns, every single one of these looks like a solidly positive month — a model trained on raw values in a mostly-up sample will learn mainly to predict "up," since that's true almost everywhere. Ranked from best to worst: stock C (rank 1, ), stock A (rank 2, ), stock E (rank 3, ), stock B (rank 4, ), stock D (rank 5, ). The rank labels immediately isolate that C and A were the relative winners and D was the relative laggard, information that's completely invisible if you only look at the fact that every single return that month happened to be positive.
Why this matters for pooling across time
Cross-sectional rank targets also make it far easier to pool training data across very different market regimes — a rally month and a crash month both get compressed onto the same rank scale (1 through , or 0% to 100%), so a model trained across years of history isn't dominated by whichever periods happened to have the largest raw return dispersion. Without this normalisation, a handful of extreme market-wide months (a crash, a melt-up) can dominate a squared-error loss purely because of their scale, not because they contain more genuinely useful cross-sectional information.
Compare sample means across different parent shapes above — cross-sectional ranking is doing something similar at each date: recentering that period's whole distribution of returns onto a common, comparable scale before the label is used.
What this means in practice
Rank-based cross-sectional targets are the standard label for factor and machine-learning models feeding long-short equity portfolio construction, since long-short portfolios are themselves inherently relative bets — they profit from the spread between winners and losers, not from the market's absolute direction, so the training target should measure exactly that spread.
Cross-sectional rank (or z-score) targets convert raw returns into a measure of relative performance within each period's universe, removing the common market-wide component so a model learns which stocks outperformed their peers rather than simply detecting whether the whole market moved that period.
A common mistake is computing the rank or z-score using a universe that changes composition over time without care — for instance, ranking a stock against a universe list that was only finalized with hindsight (including stocks that later got added to an index, excluding ones that were later delisted). The cross-section used for ranking on any given date must reflect only what was actually knowable and tradeable as of that date.
Related concepts
Practice in interviews
Further reading
- Gu, Kelly & Xiu, Empirical Asset Pricing via Machine Learning
- Grinold & Kahn, Active Portfolio Management, ch. 3