Run a debt-to-equity screen across the whole Indian market and you will exclude nearly every bank. Not because banks are badly run, but because a bank’s balance sheet is supposed to look like that — deposits are liabilities, lending is the business, and leverage is the product rather than a warning sign.
Run a return-on-equity screen across the same market and you will over-select software and consumer brands, because those businesses hold very little capital relative to what they earn. High ROE there is a statement about asset intensity, not about management quality.
In both cases the screen has quietly stopped ranking companies and started ranking sectors.
The problem stated precisely
A factor screen assumes the metric is comparable across everything it ranks. For accounting ratios, that assumption fails in a structured way: each sector has its own level for most ratios, set by its business model rather than by how well any individual firm is run.
A cross-sectional z-score computed over the whole market therefore decomposes into two parts — how far the sector’s average sits from the market average, and how far the company sits from its own sector’s average. The first is usually much larger. So the ranking is dominated by the sector term, and what looks like a quality portfolio is substantially a bet that asset-light sectors will outperform.
Sometimes that bet works. But you did not choose it, you cannot size it, and it is not what the factor literature documents.
The fix: score within groups
Sector-neutral scoring computes the z-score within each sector and then ranks on the combined result. A bank is compared against banks, an IT company against IT companies.
The question changes from “does this company have low leverage?” to “does this company have low leverage for a bank?” — which is the question that actually generalises, and the one that carries information about management rather than about industry structure.
FactorScoreRule:
factors: roe (higher better, weight 2)
debt_to_equity (lower better, weight 1)
group_by: sector <- the whole difference
This is not a niche refinement. It is standard construction in institutional factor products, and the reason is exactly the above: an un-neutralised factor portfolio has sector bets in it that nobody chose.
The complementary control: cap the sector
Neutral scoring fixes the input side. It does not fix the output.
Even with perfectly sector-neutral scores, the top 30 can happen to contain twelve financials — if financials genuinely had the best within-sector scores that quarter. The ranking logic has no notion of concentration; it just takes the best 30 numbers.
A sector cap addresses that directly: no group may exceed some share of the book, with the trimmed weight redistributed across the uncapped names. NSE applies caps of this kind across its factor indices for the same reason, alongside single-stock caps.
The two controls are genuinely independent and both are needed:
| Control | Fixes | Failure it prevents |
|---|---|---|
group_by='sector' on the score | Input comparability | Ranking sectors instead of companies |
max_group_weight on constraints | Output concentration | 40% of the book in one sector by accident |
Why this was not possible until now
A note on the plumbing, because it explains a real gap.
Three rules in this engine accept a group_by argument — the factor score, the constraints, and the rolling z-score — and all three cite sector-neutrality as the motivating case. None of them could actually do it, because there was no sector field to group by.
The data was always there: every security carries a sector foreign key, and the resolver’s security axis already selected it. The blocker was narrower and more annoying. The data layer identifies a security by the column ticker_id, which is correct for every table that references a security — daily prices, surveillance flags, index membership. It is wrong for the security’s own table, where the identifier is the primary key ticker. A field sourced from Security therefore generated SELECT ticker_id ... FROM collector_security and failed.
The fix was to let a field declare its own entity column when it differs from the default. That one addition unlocked sector, and with it sector-neutral scoring and sector caps across all three rules — plus the instrument attributes that live on the same table, like a bond’s category and coupon.
Worth stating because it is a general pattern: a capability can be absent from a product not because the data is missing or the feature is unbuilt, but because of a small mismatch in the seam between them.
Honest caveats
Sector classification is not complete. Roughly three-quarters of Indian securities carry a canonical sector; the remainder are mostly delisted or thinly covered names. The template requires a classified sector before scoring, so unclassified names are excluded rather than silently pooled into a junk group — which is the right trade, but it does narrow the universe.
Sector-neutral is not automatically better. If a sector genuinely deserves to outperform, neutralising removes a source of return. What it buys is that your factor exposure is the factor rather than an unexamined industry bet. If you want the industry bet, take it deliberately and size it.
Sector boundaries are a judgment. Is a payments company financial services or technology? Different taxonomies answer differently, and the answer moves the score.
Try it
The Sector-Neutral Quality 30 template scores ROE and leverage within sectors, holds the top 30 under the NSE score transform, and caps any single sector at 25% and any single name at 8%.
Run it against the un-neutralised Quality 30 and compare the holdings, not just the returns. The sector-neutral version will hold financials, which the plain version largely cannot. Whether that improves returns varies by period; that it changes what the strategy is actually betting on does not.
Further reading
- The quality factor: screening for businesses, not charts is the screen this distortion affects most, since ROE and leverage are largely sector properties
- Value screens that survive contact with Indian data for the same problem inside price-to-book
- Top 30 or top decile? on the capping half of the control described here
Glossary: sector neutral, factor investing, concentration limit, z-score.