Decompose portfolio returns into known risk premia. Build a custom factor when the standard ones don't capture what your edge is loading on.
W4 introduced the major equity factors — Market, Size (SMB), Value (HML), Momentum (UMD), Quality, Low Vol — and noted that they have multi-year drawdowns. This week is how to actually use them: regress portfolio returns on factor returns to read off exposures and separate alpha from beta.
By Friday you should be able to:
The reading is the original Fama-French (1993) paper and Carhart (1997); Palomar Ch 7 §2 covers the regression interpretation. Cochrane (2001) Ch 12–13 has the standard-error theory if you want to go deeper.
A factor model decomposes an asset's excess return into a weighted sum of common-factor returns plus an idiosyncratic residual. Both Merton's ICAPM and Ross's APT motivate the same form — factors must carry an economic reason to predict returns.
\[ R_{i,t} - R_{f,t} \;=\; \alpha_i \;+\; \sum_{k=1}^{K} \beta_{i,k}\, F_{k,t} \;+\; \varepsilon_{i,t} \quad (1) \]A second, cross-sectional equation links expected returns to factor risk premia \( \lambda_k \):
\[ \mathbb{E}[R_i - R_f] \;=\; \lambda_0 \;+\; \sum_{k=1}^{K} \beta_{i,k}\, \lambda_k \quad (2) \]Under a correctly specified model, \( \lambda_0 = 0 \) — no return without exposure. The \( \beta_{i,k} \) is the asset's loading on factor \( k \); the \( \lambda_k \) is the risk premium the market pays per unit of that exposure.
What plays the role of \( F_{k,t} \) depends on the factor type:
Two estimation routes match these two cases (covered below): time-series regression for traded-portfolio factors, Fama-MacBeth two-pass for macro factors. QT uses time-series exclusively — we're auditing what the live book is exposed to, not pricing new assets.
Every model below is the same equation above with a different choice of factors.
| Model | Factors | What it adds |
|---|---|---|
| CAPM (Sharpe-Lintner, 1964) |
Mkt − Rf | The baseline. Only systematic (market) risk should be compensated. Empirically inadequate — small and value stocks earn more than CAPM predicts. |
| Fama-French 3 (1993) |
Mkt − Rf, SMB, HML | Adds Size and Value premia. Explains roughly 90%+ of US-equity cross-sectional return variance. |
| Carhart 4 (1997) |
+ UMD (a.k.a. MOM) | Adds Momentum (Up-Minus-Down). Essential when evaluating any trend-following or momentum strategy. |
| Fama-French 5 (2015) |
+ RMW, CMA | Adds Profitability (Robust-Minus-Weak) and Investment (Conservative-Minus-Aggressive). Subsumes much of HML; better empirical fit post-2000. |
Written out, the four-factor Carhart model is:
\[ R_{p,t} - R_{f,t} \;=\; \alpha_p \;+\; \beta_{\mathrm{MKT}}(R_{M,t} - R_{f,t}) \;+\; \beta_{\mathrm{SMB}}\,\mathrm{SMB}_t \;+\; \beta_{\mathrm{HML}}\,\mathrm{HML}_t \;+\; \beta_{\mathrm{MOM}}\,\mathrm{MOM}_t \;+\; \varepsilon_{p,t} \]This is the default QT uses for portfolio decomposition. FF5 is worth running as a robustness check.
W4 told you what SMB and HML mean ("Small Minus Big", "High Minus Low book-to-market"). The factor returns Fama and French publish on their data library are not just SMB = small-cap index minus large-cap index. They come from a specific 2×3 sort that isolates each premium from the other.
Every June, the universe (NYSE + AMEX + NASDAQ common stocks) is sorted on two characteristics simultaneously:
The intersection gives six value-weighted portfolios: SL, SM, SH, BL, BM, BH. The factor returns are then:
\[ \mathrm{SMB}_t = \tfrac{1}{3}(R_{\mathrm{SL}} + R_{\mathrm{SM}} + R_{\mathrm{SH}})_t \;-\; \tfrac{1}{3}(R_{\mathrm{BL}} + R_{\mathrm{BM}} + R_{\mathrm{BH}})_t \] \[ \mathrm{HML}_t = \tfrac{1}{2}(R_{\mathrm{SH}} + R_{\mathrm{BH}})_t \;-\; \tfrac{1}{2}(R_{\mathrm{SL}} + R_{\mathrm{BL}})_t \]Two design choices in here are worth internalizing:
The Fama-French recipe generalizes. Any cross-sectional stock characteristic can be turned into a factor by sorting and going long-short.
Characteristic: gross profitability = (Revenue − COGS) / Total Assets, as in Novy-Marx (2013).
At each June, rank the universe, form a long-short portfolio of top-quintile minus bottom-quintile. Call the factor return QMJ (Quality-Minus-Junk). Regress QMJ against the FF3 + MOM factors. Novy-Marx reports a significant positive intercept of ~0.3% per month with \( R^2 \) around 0.30 — the quality premium isn't captured by Mkt / SMB / HML / MOM, so it's a real fifth factor.
Equations (1) and (2) suggest two regression strategies. Which one you use depends on whether your factors are traded portfolios or general macroeconomic surprises.
When factors are returns (SMB, HML, MOM): fit equation (1) directly per asset or portfolio with OLS. The \( \beta_{i,k} \) are the slopes. The factor risk premium \( \lambda_k \) is just the time-series mean of \( F_{k,t} \).
The asset-pricing test is whether \( \alpha_i = 0 \) jointly across all assets — the GRS F-test (Gibbons, Ross & Shanken 1989), HAC-adjusted for autocorrelation.
QT default. Tractable in pandas + statsmodels; this is what the rest of this week uses.
When factors are macroeconomic surprises or otherwise non-traded:
Rolling 60-month windows are the standard. Standard errors must correct for the fact that the \( \hat\beta \)s are themselves estimated — Fama-MacBeth (1973) gave the original adjustment; Cochrane (2001) Ch 12 has the modern treatment.
More relevant to QR asset-pricing work than to QT portfolio decomposition.
Once factors exist, decomposing a portfolio's returns is just OLS:
import pandas as pd, statsmodels.api as sm
# portfolio_excess = monthly portfolio return - monthly Rf
# factors = DataFrame with columns ['MKT_RF', 'SMB', 'HML', 'MOM']
X = sm.add_constant(factors)
model = sm.OLS(portfolio_excess, X).fit(
cov_type='HAC', cov_kwds={'maxlags': 6} # Newey-West, accounts for autocorrelation
)
print(model.summary())
Three notes on the regression itself:
The intercept. Portfolio's average excess return not attributable to factor exposures. Under a correctly specified model the asset-pricing prediction is \( \alpha = 0 \); a significant non-zero \( \alpha \) means either (a) the model is missing a factor, or (b) the portfolio has true skill that no factor captures.
If \( \alpha \) is negative, you're paying for factor exposure you could get cheaper through a factor ETF.
Each \( \beta_k \) is the portfolio's exposure to factor \( k \). \( \beta_{\mathrm{MOM}} = 0.4 \) means a 1% MOM factor return contributes 0.4% to the portfolio that month.
Sign matters: \( \beta_{\mathrm{HML}} < 0 \) is a growth tilt; \( \beta_{\mathrm{HML}} > 0 \) is a value tilt.
Fraction of return variance explained by the factors. \( R^2 = 0.90 \) means 90% of the portfolio's monthly variance comes from factor exposures; only 10% is idiosyncratic.
High \( R^2 \) is not bad — it means the model is doing its job. The question is what's left in the residual.
The unexplained portion of returns. Its variance is the portfolio's idiosyncratic risk. If two strategies have similar betas but different residual variance, the lower-residual one is more "factor-like" and less likely to surprise.
A hypothetical multi-strategy portfolio, 48 months of returns. Regress against Carhart 4-factor + a custom Quality factor (QMJ). OLS with Newey-West errors:
| Term | Estimate | t-stat | Interpretation |
|---|---|---|---|
| α (monthly) | 0.04% | 0.6 | Not statistically distinguishable from zero. No skill premium after factors. |
| βMKT | 0.85 | 14.2 | High market exposure — the portfolio moves 85¢ for every $1 of market. |
| βSMB | 0.22 | 2.4 | Significant small-cap tilt. |
| βHML | -0.18 | -1.9 | Marginal growth tilt (negative value loading). |
| βMOM | 0.35 | 3.8 | Strong momentum exposure. |
| βQMJ | 0.15 | 1.6 | Borderline quality tilt; not statistically robust. |
| R² | 0.87 | — | 87% of variance explained by the 5 factors. |
Given the decomposition above, the QT takeaway is: