Risk Metrics

Selection vs drift decomposition

Splits a book's realized residual return into two parts:

  • Selection — what the book earned by holding names that beat their cohort's average residual.
  • Drift — what it earned purely from net exposure to that average, which accrues on net weight regardless of any selection skill.

The two sum to the total exactly. This is an identity, not a fitted attribution:

R_t = Σ_i w_i·(ε_i,t − μ_c(i),t) + Σ_c W_c·μ_c,t

where w_i is a position weight, ε_i,t its residual, μ_c,t its cohort's mean residual, and W_c the net weight in cohort c.

This answers "was I paid for stock-picking, or for being net long the average stock?" — a question that is only answerable because ERM3 fits residuals without an intercept, leaving a non-zero cross-sectional mean that the cohort store exposes.

Levels must match: level=sector (default) demeans each name's sector-level residual against its sector cohort; level=market uses market-level residuals against the market cohort.

Weights are treated as constant over the window and are not normalized — rescaling them would change the drift term, which is proportional to net weight. Positions that cannot be resolved or mapped to an addressable cohort are dropped and named in coverage.dropped rather than silently omitted.

Realized historical attribution only — not a forecast, not a backtest of a strategy, and not a recommendation regarding any security.

post/cohorts/pnl-decomposition

Request

  • Base URL: https://riskmodels.app/api
  • URL: https://riskmodels.app/api/cohorts/pnl-decomposition
  • Auth: HTTP bearer

Request body

level'market' | 'sector'
start_datestring date
end_datestring date
min_namesinteger

Ignore cohort means on days the cohort had fewer than this many members.

include_seriesboolean

Include the daily selection/drift series.

Response

Selection vs drift decomposition

level'market' | 'sector'
basisstring

Which stock residual was used and which cohort mean it was demeaned against.

rangestring[] nullable
n_daysinteger
net_weightnumber
gross_weightnumber
store_buildstring nullable

Changes

No recorded changes to this operation across all 1 revision of this API.