CovEst.2003LW {CovTools}R Documentation

Covariance Estimation with Linear Shrinkage


Ledoit and Wolf (2003, 2004) proposed a linear shrinkage strategy to estimate covariance matrix with an application to portfolio optimization. An optimal covariance is written as a convex combination as follows,

\hat{Σ} = δ \hat{F} + (1-δ) \hat{S}

where δ \in (0,1) a control parameter/weight, \hat{S} an empirical covariance matrix, and \hat{F} a target matrix. Although authors used F a highly structured estimator, we also enabled an arbitrary target matrix to be used as long as it's symmetric and positive definite of corresponding size.


CovEst.2003LW(X, target = NULL)



an (n\times p) matrix where each row is an observation.


target matrix F. If target=NULL, constant correlation model estimator is used. If target is specified as a qualified matrix, it is used instead.


a named list containing:


a (p\times p) covariance matrix estimate.


an estimate for convex combination weight according to the relevant theory.


Ledoit O, Wolf M (2003). “Improved estimation of the covariance matrix of stock returns with an application to portfolio selection.” Journal of Empirical Finance, 10(5), 603–621. ISSN 09275398.

Ledoit O, Wolf M (2004). “A well-conditioned estimator for large-dimensional covariance matrices.” Journal of Multivariate Analysis, 88(2), 365–411. ISSN 0047259X.

Ledoit O, Wolf M (2004). “Honey, I Shrunk the Sample Covariance Matrix.” The Journal of Portfolio Management, 30(4), 110–119. ISSN 0095-4918.


## CRAN-purpose small computation
# set a seed for reproducibility

#  small data with identity covariance
pdim      <- 5
dat.small <- matrix(rnorm(20*pdim), ncol=pdim)

#  run the code with highly structured estimator
out.small <- CovEst.2003LW(dat.small)

#  visualize
opar <- par(no.readonly=TRUE)
par(mfrow=c(1,3), pty="s")
image(diag(5)[,pdim:1], main="true cov")
image(cov(dat.small)[,pdim:1], main="sample cov")
image(out.small$S[,pdim:1], main="estimated cov")

## Not run: 
## want to see how delta is determined according to
#  the number of observations we have.
nsamples = seq(from=5, to=200, by=5)
nnsample = length(nsamples)

#  we will record two values; delta and norm difference = rep(0, nnsample)
vec.normd = rep(0, nnsample)
for (i in 1:nnsample){
  dat.norun <- matrix(rnorm(nsamples[i]*pdim), ncol=pdim) # sample in R^5
  out.norun <- CovEst.2003LW(dat.norun)                   # run with default[i] = out.norun$delta
  vec.normd[i] = norm(out.norun$S - diag(pdim),"f")       # Frobenius norm

# let's visualize the results
opar <- par(no.readonly=TRUE)
plot(nsamples,, lwd=2, type="b", col="red", main="estimated deltas")
plot(nsamples, vec.normd, lwd=2, type="b", col="blue",main="Frobenius error")

## End(Not run)

[Package CovTools version 0.5.4 Index]