I am re-reading Grinold & Kahn's Active Portfolio Management and writing the math out as I go (using AI). These are distillations for my own benefit. Rest of chapters will follow.
Grinold & Kahn, Active Portfolio Management, Ch. 3 technical appendix.
A covariance matrix of \(N\) assets has \(N(N+1)/2\) distinct entries. \(N = 1000\) yields 500,500 entries. Estimating a covariance matrix requires 83 years of monthly returns in order to have full rank. However, an optimizer will still find a value of \(\mathbf V^{-1}\), albeit misleading. Practitioners estimate \(\mathbf V\) by imposing structure on returns rather than estimating it entry by entry. This factor model describes returns with a handful of common drivers and assembles \(\mathbf V\) out of those instead.
| \(N,\ K\) | Number of assets and number of factors, \(K \ll N\). |
| \(\mathbf r\) | \(N\times 1\) asset excess returns realized over period \(t\). |
| \(\mathbf X\) | \(N\times K\) exposure matrix. \(X_{nk}\) is asset \(n\)'s exposure to factor \(k\). Known at the end of \(t-1\). |
| \(\mathbf b\) | \(K\times 1\) factor returns realized over \(t\). Not directly observed. |
| \(\mathbf u\) | \(N\times 1\) specific returns — the part of \(\mathbf r\) no factor explains. |
| \(\mathbf F\) | \(K\times K\) covariance matrix of \(\mathbf b\). |
| \(\boldsymbol\Delta\) | \(N\times N\) covariance matrix of \(\mathbf u\); assumed diagonal, \(\Delta_{nn} = \operatorname{Var}(u_n)\). |
| \(\mathbf h,\ \mathbf x\) | \(N\times 1\) holdings and the portfolio's \(K\times 1\) factor exposures, \(\mathbf x = \mathbf X^{T}\mathbf h\). |
The model is built in four steps:
Every asset's return over period \(t\) splits into a part explained by its factor exposures and a residual. The exposures are dated \(t-1\) because they are fixed before the period runs:
\[ \mathbf r_t = \mathbf X_{t-1}\,\mathbf b_t + \mathbf u_t \tag{1} \]The period subscripts are dropped below wherever only one period is in play.
Part 2 — Building the model
Every entry of \(\mathbf X_{t-1}\) has to be measurable before period \(t\) begins, which rules out anything derived from the returns it is meant to explain. The columns come in two kinds.
Industry columns. \(X_{nk} = 1\) if asset \(n\) is in industry \(k\), else 0; conglomerates get fractional membership by sales or assets, and the row still sums to one. These absorb the co-movement that comes from doing the same business.
Risk-index columns. Continuous descriptors — size, value, momentum, volatility, leverage, liquidity, growth. Raw descriptors are in incompatible units (log market cap against a book-to-price ratio), so each is standardized across the estimation universe:
\[ X_{nk} = \frac{d_{nk} - \mu_k}{\sigma_k} \tag{2} \]The Barra convention takes \(\mu_k\) cap-weighted and \(\sigma_k\) equal-weighted. The two choices do different jobs, and the cap-weighted \(\mu_k\) is doing something exact. Let \(w_n\) be the benchmark's cap weights, so \(\sum_n w_n = 1\), and let \(\mu_k\) be defined with those same weights:
\[ \mu_k \;\equiv\; \sum_n w_n d_{nk} \]Then the benchmark's own exposure to risk index \(k\) is
\begin{align} \sum_n w_n X_{nk} &= \sum_n w_n\,\frac{d_{nk} - \mu_k}{\sigma_k} && \text{by eq.\,2} \\[4pt] &= \frac{1}{\sigma_k}\Big(\sum_n w_n d_{nk} - \mu_k \sum_n w_n\Big) && \sigma_k,\ \mu_k\text{ do not depend on }n \\[4pt] &= \frac{1}{\sigma_k}\Big(\sum_n w_n d_{nk} - \mu_k\Big) && \sum_n w_n = 1 \\[4pt] &= 0 && \text{by the definition of }\mu_k \tag{3} \end{align}So it is true by construction, and only for the one portfolio whose weights were used to centre the descriptor. An equal-weighted \(\mu_k\) would leave a non-zero benchmark exposure, and so would cap weights from a different index.
That zero is what makes the exposures readable: a portfolio's exposure is directly a bet against the benchmark, and \(\mathbf x = \mathbf X^{T}\mathbf h\) needs no re-centering before it is interpreted. The equal-weighted \(\sigma_k\) keeps a handful of megacaps from setting the scale, so a one-unit exposure means one cross-sectional standard deviation across the universe rather than across the index's largest members.
Four practical points, none of which appear in the algebra but all of which decide whether the fitted model is any good:
Fix a period \(t\) and write eq. 1 out one asset at a time, with \(X_{nk}\) the \((n,k)\) entry of \(\mathbf X_{t-1}\):
\[ r_{nt} \;=\; \sum_{k=1}^{K} X_{nk}\,b_{kt} \;+\; u_{nt}, \qquad n = 1,\dots,N \tag{4} \]That is \(N\) equations sharing \(K\) unknowns \(b_{1t},\dots,b_{Kt}\). Every quantity in eq. 4 belongs to the one period \(t\), and the index that runs is \(n\): the observations are assets, not dates. Since \(K \ll N\) the system is overdetermined, so it is solved by least squares, and the whole thing is run again from scratch next period.
Getting that direction backwards is the most common misreading of the model, because the better-known construction runs the other way:
| Here | Fama–French | |
| Exposures | known, from company characteristics | estimated |
| Factor returns | estimated | known, as constructed portfolio returns |
| A regression spans | the \(N\) stocks in one period | the \(T\) months for one stock |
| Regressions run | one per period | one per stock |
| Exposures change | when the company does | when a rolling window catches up |
| A stock with no history | still has a cap and an industry, so it has exposures | cannot be fitted |
OLS to get \(\mathbf b\). Minimizing \(\mathbf u^{T}\mathbf u = (\mathbf r - \mathbf X\mathbf b)^{T}(\mathbf r - \mathbf X\mathbf b)\) gives
\[ \hat{\mathbf b} = \left(\mathbf X^{T}\mathbf X\right)^{-1}\mathbf X^{T}\mathbf r \tag{5} \]which weights every stock equally. But specific risk is strongly heteroskedastic — a micro-cap's specific volatility runs several times a mega-cap's — so equal weighting lets the noisiest assets in the cross-section drive the estimate. Weighting each observation by its precision \(1/\Delta_{nn}\) instead means minimizing \((\mathbf r - \mathbf X\mathbf b)^{T}\boldsymbol\Delta^{-1}(\mathbf r - \mathbf X\mathbf b)\):
By Gauss–Markov this is the minimum-variance linear unbiased estimator when the residuals are uncorrelated with unequal variances, which is precisely a diagonal \(\boldsymbol\Delta\) with unequal entries — though only with the true \(\boldsymbol\Delta\), since substituting an estimate for it matches the bound only asymptotically. OLS is the special case \(\boldsymbol\Delta = \sigma^{2}\mathbf I\): equal weighting is optimal only if every stock carries the same specific risk, which no equity universe does. In practice \(1/\Delta_{nn}\) is often approximated by market cap or its square root, since specific variance falls roughly with size.
Full column rank. Both estimators invert a \(K\times K\) matrix built from \(\mathbf X\), so \(\mathbf X\) must have rank \(K\) or neither has a unique solution. The industry columns of §2.1 are the standard way this fails: every asset belongs somewhere, so those columns sum to \(\mathbf e\), the vector of ones, and adding a market or intercept column makes \(\mathbf X\) rank-deficient. Two standard fixes: drop one industry, which makes every industry return relative to the omitted one, or keep all of them and impose a constraint such as \(\sum_k c_k b_k = 0\), where \(c_k\) is industry \(k\)'s share of total market capitalization, which keeps the industries symmetric and interprets the intercept as the market return.
Equation 6 is linear in \(\mathbf r\). Write it as \(\hat{\mathbf b} = \mathbf H^{T}\mathbf r\) and read off the \(N\times K\) matrix that does it:
\[ \mathbf H^{T} = \left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right)^{-1}\mathbf X^{T}\boldsymbol\Delta^{-1}, \qquad \mathbf H = \boldsymbol\Delta^{-1}\mathbf X\left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right)^{-1} \tag{7} \]Column \(k\) of \(\mathbf H\) is a vector of holdings, and \(\hat b_k = \mathbf h_k^{T}\mathbf r\) is that portfolio's return. So each estimated factor return is the realized return on an actual portfolio, not a statistical abstraction. Whatever the factor did this month, some book of long and short positions earned exactly that.
What those portfolios hold is pinned down by one identity:
\[ \mathbf H^{T}\mathbf X = \left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right)^{-1}\left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right) = \mathbf I_K \tag{8} \]Entry \((k,l)\) of \(\mathbf H^{T}\mathbf X\) is portfolio \(k\)'s exposure to factor \(l\). So portfolio \(k\) has unit exposure to factor \(k\) and zero exposure to every other factor: it is a pure bet on one factor, hedged against the rest.
What these portfolios minimize. For a single attribute \(\mathbf a\), the minimum-variance portfolio holding one unit of exposure to it — \(\min_{\mathbf h}\mathbf h^{T}\mathbf V\mathbf h\) subject to \(\mathbf h^{T}\mathbf a = 1\) — is called the characteristic portfolio of \(\mathbf a\), and works out to \(\mathbf V^{-1}\mathbf a/(\mathbf a^{T}\mathbf V^{-1}\mathbf a)\). Column \(k\) of eq. 7 solves the same problem with \(\boldsymbol\Delta\) in place of \(\mathbf V\), and \(K\) constraints in place of one:
\[ \min_{\mathbf h}\ \mathbf h^{T}\boldsymbol\Delta\mathbf h \qquad\text{s.t.}\qquad \mathbf X^{T}\mathbf h = \mathbf e_k \tag{9} \]Appendix A does the Lagrangian; at \(K = 1\) it collapses to \(\boldsymbol\Delta^{-1}\mathbf a/(\mathbf a^{T}\boldsymbol\Delta^{-1}\mathbf a)\), the characteristic-portfolio formula with \(\mathbf V \to \boldsymbol\Delta\).
They are estimation devices, not trades. Nothing in eq. 9 mentions turnover, borrow, position limits, or transaction costs. Factor portfolios typically hold thousands of names at tiny weights, carry large gross exposure relative to net, rebalance completely every period by construction, and take positions in assets no one can short. Tradeable factor products are separate objects, built with those constraints in the optimization.
The circularity. Equation 6 needs \(\boldsymbol\Delta\), but \(\boldsymbol\Delta\) is estimated from the variance of the regression residuals \(\hat{\mathbf u} = \mathbf r - \mathbf X\hat{\mathbf b}\), which needs \(\hat{\mathbf b}\). Two ways out, usually combined: iterate within a period — start from OLS or a size proxy, form residuals, re-weight, repeat until the estimates settle — or use \(\hat{\boldsymbol\Delta}\) from prior periods, which is what production systems do, since a lagged estimate cannot introduce look-ahead and specific variances move slowly.
From the panel to \(\mathbf F\) and \(\boldsymbol\Delta\). Running eq. 6 each month for \(t = 1,\dots,T\) gives a panel \(\{\hat{\mathbf b}_t\}\) of \(K\) time series. Then \(\mathbf F\) is the sample covariance matrix of those series and \(\Delta_{nn}\) is the time-series variance of asset \(n\)'s residuals \(\hat u_{nt}\). Both are ordinary time-series estimates — but now on \(K\) series rather than \(N\), which is the whole reason the exercise is tractable.
Each period's regression used a different \(\mathbf X_{t-1}\), so the panel is only comparable across periods because the descriptors are re-standardized every period by eq. 2. That is what fixes the units: \(\hat b_{tk}\) means the same thing in every \(t\) — the return to a one-cross-sectional-standard-deviation bet on characteristic \(k\) — so covariances taken down the panel are meaningful. Standardization is not cosmetic; without it factor returns from different decades would be denominated differently and \(\mathbf F\) would be an average of incompatible numbers.
\(\hat{\mathbf b}_t\) is an estimate, not the factor return itself, so its sample covariance carries estimation error on top of the true \(\mathbf F\) and is biased upward. Production models correct for this, and typically also shrink \(\mathbf F\) and scale it to match realized volatility.
Take \(\mathbf b\) and \(\mathbf u\) centered. \(\mathbf V\) is a covariance, which is mean-insensitive. Then \(\mathbf V = \operatorname{Var}(\mathbf r) = \mathbb E[\mathbf r\mathbf r^{T}]\).
\begin{align} \mathbf V &= \mathbb E\big[(\mathbf X\mathbf b + \mathbf u)(\mathbf X\mathbf b + \mathbf u)^{T}\big] && \text{by eq. 1} \\[4pt] &= \mathbb E\big[\mathbf X\mathbf b\mathbf b^{T}\mathbf X^{T}\big] + \mathbb E\big[\mathbf X\mathbf b\mathbf u^{T}\big] + \mathbb E\big[\mathbf u\mathbf b^{T}\mathbf X^{T}\big] + \mathbb E\big[\mathbf u\mathbf u^{T}\big] && \text{expand} \\[4pt] &= \mathbf X\,\mathbb E[\mathbf b\mathbf b^{T}]\,\mathbf X^{T} + \mathbf X\,\mathbb E[\mathbf b\mathbf u^{T}] + \mathbb E[\mathbf u\mathbf b^{T}]\,\mathbf X^{T} + \mathbb E[\mathbf u\mathbf u^{T}] && \mathbf X\text{ is known at }t-1 \\[4pt] &= \mathbf X\mathbf F\mathbf X^{T} + \mathbf X\operatorname{Cov}(\mathbf b,\mathbf u) + \operatorname{Cov}(\mathbf u,\mathbf b)\,\mathbf X^{T} + \boldsymbol\Delta && \text{definitions of }\mathbf F,\ \boldsymbol\Delta \\[4pt] &= \mathbf X\mathbf F\mathbf X^{T} + \boldsymbol\Delta && \operatorname{Cov}(\mathbf b,\mathbf u) = \mathbf 0 \tag{10} \end{align}Equation 10 read as a forecast. Standing at date \(t\) and wanting next month's covariance matrix, eq. 10 says
\[ \hat{\mathbf V}_{t+1} = \mathbf X_t\,\hat{\mathbf F}_t\,\mathbf X_t^{T} + \hat{\boldsymbol\Delta}_t \tag{11} \]\(\mathbf X_t\) determines the exposures that will govern next month's returns based on today's market capitalizations, book-to-price ratios and industry memberships. \(\mathbf F\) and \(\boldsymbol\Delta\) are estimated from history, so they describe factor behaviour in general. \(\hat{\mathbf F}_t\) is \(K\times K\), and the same \(\hat{\mathbf F}_t\) is used for every pair of stocks, so it cannot be what makes one pair differ from another. \(\mathbf X_t\) is \(N\times K\), one row per stock: row \(n\) holds stock \(n\)'s own characteristics, so Apple's row and Pfizer's row are different numbers, and that difference is the only thing separating one covariance from another.
A sample covariance matrix has one input and one only, past returns, with no slot for the fact that a company is now ten times the size it was. Five years a micro-cap and then a tripling leaves sixty monthly observations of which fifty-nine describe the small version of it, and they clear the window one month at a time. Recomputing \(\mathbf X_t\) today moves that stock's size exposure at once. The exception is \(\hat{\boldsymbol\Delta}_t\), one variance per asset taken from that asset's own past residuals, so specific risk lags in exactly the way a sample estimate does.
The subscripts on \(\hat{\mathbf F}_t\) and \(\hat{\boldsymbol\Delta}_t\) mark them as estimated from history through \(t\), and that history was built from the past exposures \(\mathbf X_0,\dots,\mathbf X_{t-1}\) (§2.2). Today's \(\mathbf X_t\) appears in eq. 11 and nowhere else — it is information no historical estimate contains.
Factor and specific returns are uncorrelated: \(\operatorname{Cov}(\mathbf b,\mathbf u) = \mathbf 0\). This is what kills the two cross terms in the derivation above.
\(\boldsymbol\Delta\) is diagonal: specific returns are mutually uncorrelated. Note this one is not needed for eq. 10 — the identity holds for any \(\boldsymbol\Delta\). It is needed for the entry-by-entry reading and the parameter count below.
Dimension check. \(\mathbf X\) is \(N\times K\), \(\mathbf F\) is \(K\times K\), \(\mathbf X^{T}\) is \(K\times N\), so \(\mathbf X\mathbf F\mathbf X^{T}\) is \(N\times N\) and conformable with \(\boldsymbol\Delta\). Both terms are symmetric, so \(\mathbf V\) is.
Entry by entry.
\[ V_{ij} = \sum_{k}\sum_{l} X_{ik}F_{kl}X_{jl} + \Delta_{ij} \tag{12} \]Because \(\boldsymbol\Delta\) is diagonal the second term vanishes for \(i \ne j\), so two different assets covary only through their factor exposures. Two biotech firms are correlated because both load on the same industry and size factors, not because the model was told anything about the pair. The converse is the restriction: two stocks with identical rows of \(\mathbf X\) get identical covariance with every other asset, and differ only in \(\Delta_{nn}\).
Parameter count. \(\mathbf F\) contributes \(K(K+1)/2\) and diagonal \(\boldsymbol\Delta\) contributes \(N\). Sixty factors over a thousand assets is \(1830 + 1000 = 2830\) parameters against 500,500 — 177 times fewer. The \(NK\) numbers in \(\mathbf X\) are not estimated at all.
Part 3 — Using the model
Substituting eq. 10 into portfolio variance and collecting \(\mathbf X^{T}\mathbf h\):
\begin{align} \sigma_P^{2} = \mathbf h^{T}\mathbf V\mathbf h &= \mathbf h^{T}\left(\mathbf X\mathbf F\mathbf X^{T} + \boldsymbol\Delta\right)\mathbf h && \text{by eq. 10} \\[4pt] &= \left(\mathbf X^{T}\mathbf h\right)^{T}\mathbf F\left(\mathbf X^{T}\mathbf h\right) + \mathbf h^{T}\boldsymbol\Delta\mathbf h && \text{regroup} \\[4pt] &= \underbrace{\mathbf x^{T}\mathbf F\mathbf x}_{\text{common factor}} + \underbrace{\mathbf h^{T}\boldsymbol\Delta\mathbf h}_{\text{specific}} \tag{13} \end{align}Every attribution report is a reading of eq. 13. The first term depends on the portfolio only through its \(K\) factor exposures \(\mathbf x\), so two portfolios with different holdings and the same exposures carry identical common-factor risk. The second is \(\sum_n h_n^{2}\Delta_{nn}\) for diagonal \(\boldsymbol\Delta\), which shrinks like \(1/N\) as holdings spread out: an equal-weighted book drives specific risk toward zero while its common-factor risk stays put. That is the precise sense in which factor risk is the part diversification cannot remove.
Why §2.2 could minimize over \(\boldsymbol\Delta\). Using \(\boldsymbol\Delta\) rather than \(\mathbf V\) changes nothing, because the constraint has already spent the factor risk:
\begin{align} \mathbf h^{T}\mathbf V\mathbf h &= \mathbf x^{T}\mathbf F\mathbf x + \mathbf h^{T}\boldsymbol\Delta\mathbf h && \text{by eq. 13} \\[4pt] &= \mathbf e_k^{T}\mathbf F\mathbf e_k + \mathbf h^{T}\boldsymbol\Delta\mathbf h && \mathbf x = \mathbf X^{T}\mathbf h = \mathbf e_k\text{, by eq. 9} \\[4pt] &= F_{kk} + \mathbf h^{T}\boldsymbol\Delta\mathbf h \tag{14} \end{align}\(F_{kk}\) is the same number for every feasible \(\mathbf h\), so minimizing total variance and minimizing specific variance are the same problem here and have the same minimizer. \(\boldsymbol\Delta\) appears because GLS weights by the covariance of the regression's errors, and it survives into the portfolio statement because requiring unit exposure to one factor and zero to the rest has already fixed the common-factor variance at \(F_{kk}\).
What the construction leans on.
Claim: column \(k\) of \(\mathbf H\) in eq. 7 solves eq. 9. The Lagrangian carries a \(K\times 1\) multiplier \(\boldsymbol\lambda\), one per constraint:
\begin{align} L(\mathbf h,\boldsymbol\lambda) &= \tfrac12\,\mathbf h^{T}\boldsymbol\Delta\mathbf h - \boldsymbol\lambda^{T}\left(\mathbf X^{T}\mathbf h - \mathbf e_k\right) && \text{one multiplier per constraint} \tag{A1} \\[4pt] \boldsymbol\Delta\mathbf h - \mathbf X\boldsymbol\lambda &= \mathbf 0 && \partial L/\partial\mathbf h = \mathbf 0 \\[4pt] \mathbf h &= \boldsymbol\Delta^{-1}\mathbf X\boldsymbol\lambda && \boldsymbol\Delta \succ 0 \tag{A2} \end{align}Imposing the constraint on eq. A2 determines \(\boldsymbol\lambda\), and substituting back gives \(\mathbf h\):
\begin{align} \mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\boldsymbol\lambda &= \mathbf e_k && \text{apply }\mathbf X^{T}\text{ to eq. A2} \\[4pt] \boldsymbol\lambda &= \left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right)^{-1}\mathbf e_k && \mathbf X\text{ full rank} \\[4pt] \mathbf h_k &= \boldsymbol\Delta^{-1}\mathbf X\left(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X\right)^{-1}\mathbf e_k = \mathbf H\mathbf e_k \tag{A3} \end{align}which is column \(k\) of eq. 7. The objective is strictly convex and the constraints affine, so this is the unique minimizer, not merely a stationary point.
The \(K = 1\) case. With one factor, \(\mathbf X\) is a single column \(\mathbf a\) and \(\mathbf e_k = 1\). Then \(\mathbf X^{T}\boldsymbol\Delta^{-1}\mathbf X = \mathbf a^{T}\boldsymbol\Delta^{-1}\mathbf a\) is a scalar and eq. A3 reads
\[ \mathbf h_a = \frac{\boldsymbol\Delta^{-1}\mathbf a}{\mathbf a^{T}\boldsymbol\Delta^{-1}\mathbf a} \tag{A4} \]The characteristic portfolio of \(\mathbf a\) from §2.2, with \(\boldsymbol\Delta\) wherever \(\mathbf V\) stood. The \(K > 1\) version adds the requirement that the portfolio be neutral to the other \(K-1\) factors.