4
votes

Is there a function that can convert a covariance matrix built using log-returns into a covariance matrix based on simple arithmetic returns?

Motivation: We'd like to use a mean-variance utility function where expected returns and variance is specified in arithmetic terms. However, estimating returns and covariances is often performed with log-returns because of the additivity property of log returns, and we assume asset prices follow a lognormal stochastic process.

Meucci describes a process to generate a arithmetic-returns based covariance matrix for a generic/arbitrary distribution of lognormal returns on Appendix page 5.

1
don't have time to do this now but it seems easy to implement based on the equations in the linked reference (you could probably even use a for loop, but outer would be better) - Ben Bolker
I think the function would need to take as input an expected returns, and covariance matrix at a horizon. Function would also need to assume a distribution (normal, cauchy, etc.). I am surprised that a library does not exist for this already -- most covariances are estimated via log returns and this should be a fairly common problem. - Ram Ahluwalia
See below. Not so sure about the distribution. Among other things, if the distribution is really Cauchy then the theoretical second moments don't exist and the sample second moments don't mean very much ... - Ben Bolker

1 Answers

3
votes

Here's my translation of the formulae:

linreturn <- function(mu,Sigma) {
  m <- exp(mu+diag(Sigma)/2)-1
  x1 <- outer(mu,mu,"+")
  x2 <- outer(diag(Sigma),diag(Sigma),"+")/2
  S <- exp(x1+x2)*(exp(Sigma)-1)
  list(mean=m,vcov=S)
}

edit: fixed -1 issue based on comments.

Try an example:

m1 <- c(1,2)
S1 <- matrix(c(1,0.2,0.2,1),nrow=2)

Generate multivariate log-normal returns:

set.seed(1001)
r1 <- exp(MASS::mvrnorm(200000,mu=m1,Sigma=S1))-1
colMeans(r1)
## [1]  3.485976 11.214211
var(r1)
##         [,1]     [,2]
## [1,] 34.4021  12.4062
## [2,] 12.4062 263.7382

Compare with expected results from formulae:

linreturn(m1,S1)

## $mean
## [1]  3.481689 11.182494

## $vcov
##          [,1]      [,2]
## [1,] 34.51261  12.08818
## [2,] 12.08818 255.01563