PCA of the Yield Curve: Level Slope Curvature

Principal-component analysis (PCA) rotates correlated yield-curve changes into orthogonal factors ranked by explained variance. In major rates markets, the leading components often resemble level, slope, and curvature, but that familiar label is an empirical result of a chosen sample, grid, and normalization—not a law of term-structure economics.

Build the data matrix correctly

Let X contain daily changes in zero rates or par swap rates: rows are dates and columns are selected maturities. PCA diagonalizes the sample covariance matrix:

Σ = (XᵀX)/(T - 1) = V diag(λ) Vᵀ
factor_score_t = X_t V

Center each tenor before estimating Σ; otherwise PCA mainly describes the average curve. Use rate changes rather than levels because levels are non-stationary, and maintain a stable tenor grid through time. A zero-rate grid derived from the same curve construction is usually cleaner than raw bond yields. See yield-curve bootstrapping for the distinction.

Design choiceWhy it mattersCommon mistake
zero versus par rateschanges factor loadingsmixing quote types
daily versus weekly moveschanges noise and regimestreating results as invariant
unweighted covariancedescribes rate variancecalling it portfolio risk
DV01-weighted covariancealigns factors to P&Llosing simple rate interpretation

Estimate and orient components

Eigenvectors have arbitrary sign. Flip each loading vector to an agreed convention—perhaps positive long-end loading for level—before reporting factor returns. Otherwise a positive “level” shock may change sign after every refit.

import numpy as np

def yield_pca(rate_changes, n_components=3):
    X = np.asarray(rate_changes)
    X = X - X.mean(axis=0, keepdims=True)
    cov = np.cov(X, rowvar=False)
    eigval, eigvec = np.linalg.eigh(cov)
    order = np.argsort(eigval)[::-1]
    eigval, eigvec = eigval[order], eigvec[:, order]
    loadings = eigvec[:, :n_components]
    # Convention: positive 10Y/last-tenor loading for every factor.
    loadings *= np.sign(loadings[-1, :])
    return loadings, eigval[:n_components], X @ loadings

The first component is generally positive across maturities: a parallel-like level move. The second usually has opposite short- and long-end signs: slope. The third normally alternates signs: curvature. Yet a crisis sample can promote front-end policy shocks, and a single-country curve can differ sharply from a cross-currency panel.

ComponentTypical loading shapeDesk interpretation
PC1same sign across tenorsduration / level risk
PC2short and long opposite2s10s or 5s30s steepening
PC3belly opposite wingsbutterfly / curvature

From statistical factor to hedge

For an instrument with key-rate DV01 vector d, approximate its sensitivity to a PCA factor loading vk by dᵀvk. To neutralize several factors, stack instrument exposure vectors into A and solve a constrained least-squares hedge:

min_h || b + A h ||² + γ ||h||²

The ridge term γ prevents huge offsetting hedge notionals when candidate hedges are nearly collinear. Use actual instrument PV changes to validate the linear approximation; duration and convexity explains why large moves, callable bonds, and changing cash flows violate it.

PCA factors are orthogonal in the historical covariance metric, not necessarily uncorrelated in future stressed markets. A factor-neutral book can retain substantial key-rate loss if a realized move falls outside the first three components. Report residual exposure to the omitted subspace and run explicit curve-twist shocks.

Stability, regimes, and leakage

Estimate rolling PCA and compare subspaces rather than individual vectors alone. A useful stability statistic is the principal angle between the old and new leading-factor spaces. If it widens, historical factor hedges are stale even where explained variance remains high.

Do not select components using future data in a backtest. Refit using only information available on each rebalance date, apply that basis forward, and include transaction costs from factor hedge turnover. A “level” factor with high explained variance is not automatically a return factor; expected returns require a separate economic hypothesis, such as carry, policy repricing, or supply-demand pressure.

Key takeaways

  • PCA summarizes correlated curve changes but depends on the data definition and estimation window.
  • Orient eigenvectors and use a fixed tenor grid to make factor reports comparable through time.
  • Translate loadings into P&L with key-rate DV01s, then validate with full repricing.
  • Factor neutrality does not eliminate risks in omitted directions, nonlinear products, or regime shifts.
  • Refit without look-ahead and measure hedge turnover as part of any PCA strategy.
#PCA #yield curve #factor models #fixed income