Class CovarianceShrinkage

java.lang.Object
com.quantfinlib.risk.CovarianceShrinkage

public final class CovarianceShrinkage extends Object
Ledoit-Wolf covariance shrinkage (2004, "A well-conditioned estimator for large-dimensional covariance matrices"): the standard fix for the dirty secret of portfolio optimization. The sample covariance matrix is the maximally overfit estimate. With N assets and T observations it has N(N+1)/2 free parameters; when T is not a large multiple of N its smallest eigenvalues are far too small and its largest far too large, and a mean-variance optimizer amplifies exactly those errors (it loads up on the directions the matrix wrongly calls near-riskless).

The estimator shrinks toward the scaled identity mu·I (mu = average sample variance):

  Sigma* = delta · mu·I + (1 − delta) · S

with the intensity delta chosen from the data to minimize expected Frobenius loss: delta = b̄²/d², where d² = ||S − mu·I||²_F measures how far the sample matrix is from the target and b̄² estimates how much of that distance is pure sampling noise (the average Frobenius distance of single-observation outer products from S, over T², clamped to d²). Intuition: when the data say the sample matrix is mostly noise (T small, N large), delta → 1 and you trust the boring target; when T is huge, delta → 0 and the sample matrix speaks for itself. No tuning parameter to pick — that is the whole appeal.

The result is always positive-definite for delta > 0 (a convex combination with mu·I lifts every eigenvalue toward mu), which is what makes it safe to hand to optimization.PortfolioOptimizer where a raw sample matrix from short history can be singular. constantCorrelation(double[][]) shrinks instead toward the constant-correlation target of Ledoit and Wolf (2003/2004, "Honey, I shrunk the sample covariance matrix", J. Portfolio Management 30(4)), which keeps each asset's own variance and replaces every correlation by the average one; it is the better target for equity books where all names share a market factor.

Units: both estimators return the population covariance (divisor T, the Ledoit-Wolf convention), while CorrelationMatrix.covariance uses the sample divisor T − 1. Do not mix the two in one risk number; the ratio is T/(T − 1) (1.7% at T = 60). Research lane, deterministic.

  • Method Details

    • ledoitWolf

      public static CovarianceShrinkage.Result ledoitWolf(double[][] returns)
      Ledoit-Wolf shrinkage estimate of the covariance matrix.
      Parameters:
      returns - T×N: returns[t][j] = period-t return of asset j; T ≥ 2, N ≥ 1, rectangular, finite
    • constantCorrelation

      public static CovarianceShrinkage.Result constantCorrelation(double[][] returns)
      Ledoit-Wolf shrinkage toward the constant-correlation target F_ii = s_ii, F_ij = r̄·√(s_ii s_jj) with r̄ the average sample correlation. The optimal intensity is δ = max(0, min(1, (π̂ − ρ̂)/(γ̂·T))) with (LW 2004, Appendix B)
        π̂ = Σ_ij (1/T) Σ_t (x_ti x_tj − s_ij)²
       ρ̂ = Σ_i π̂_ii + Σ_{i≠j} (r̄/2)·( √(s_jj/s_ii)·θ_ii,ij + √(s_ii/s_jj)·θ_jj,ij )
       θ_ii,ij = (1/T) Σ_t (x_ti² − s_ii)(x_ti x_tj − s_ij)
       γ̂ = ||F − S||²_F
      on demeaned data x. CovarianceShrinkage.Result.target() reports r̄.
      Parameters:
      returns - T×N, T ≥ 2, N ≥ 2, rectangular, finite, every asset with positive sample variance
    • shrink

      public static double[][] shrink(double[][] returns)
      Convenience: the shrunk matrix only.