Every position has a level too.
Every US equity has a market benchmark — SPY does most of the work. Many have a useful sector benchmark — XLK explains a software stock that SPY alone doesn't. Some have a meaningful subsector benchmark — SOXX explains a chip stock that XLK alone doesn't.
But not every stock has all three.
Apple's subsector is so concentrated that the "subsector hedge" for AAPL is basically a noisy short of itself. Subtracting it makes the residual worse, not cleaner. The model knows this. It can tell you.
We call the answer L*.
The picker
For each stock, on each trading day, RiskModels asks: does the next level down actually earn its place — does the variance it's expected to remove out-of-sample outweigh the added hedging cost of carrying another ETF leg?
if subsector's expected OOS variance reduction outweighs its added hedging cost: L3
else if sector's expected OOS variance reduction outweighs its added hedging cost: L2
else: L1
- L1 — one ETF, the market. The default when sector and subsector don't earn their seat.
- L2 — two ETFs, market + sector. The right answer for most large-cap stocks.
- L3 — three ETFs, market + sector + subsector. Reserved for names where the subsector layer carries real signal.
The picker is a cost-aware, statistically-learned selector: it chooses the shallowest level whose expected out-of-sample variance reduction outweighs the added hedging cost (gross notional and turnover) of going deeper. It's scored point-in-time — each date is decided only from data available up to that date, so the dispatch is backtest-safe.
What it changes for your workflow
| Old question | The L* answer |
|---|---|
| "What's the residual return on this name?" | lstar_rr — the residual at the level the model actually picked. Comparable across the whole universe. |
| "Should I hedge with three ETFs or two?" | lstar_level — 1, 2, or 3. Don't trade legs the model didn't prescribe. |
| "Why does my deep-hedge basket leak alpha on certain stocks?" | Because you were forcing L3 on names where L1 or L2 was the right depth. The subsector hedge added cost without adding cleanness. |
What clients see
lstar_rr and lstar_level ship as standard fields on every /api/metrics and /api/batch/analyze call — no separate endpoint, no extra cost. The cascade does the picking; you get the answer.
For a custom marginal-explained-risk bar instead of the default cost-aware selector, the per-ticker /api/lstar?threshold= endpoint still gives you the full historical dispatch with your choice of bar.
from riskmodels import RiskModelsClient
client = RiskModelsClient.from_env()
m = client.get_metrics("AAPL")
m["lstar_rr"] # → today's idiosyncratic return at AAPL's right depth
m["lstar_level"] # → 3 (L3) for AAPL — subsector earns its place net of cost
Where it matters
- Stat-arb desks ranking residual signals across a universe.
lstar_rris the cross-sectionally comparable residual — fixed-L3 isn't. - Allocators sizing single-name risk. The
lstar_leveltells you whether the residual you're measuring assumed a one-, two-, or three-ETF hedge stack. - AI agents answering "what's the residual?". L* keeps them from reaching for the deepest hedge by reflex when shallower is more honest.
The principle
Hierarchical risk models give you more knobs. L* tells you which knobs to actually turn.
Every position has a market benchmark. Every position has a level too.