# Generating a random covariance matrix with variances in range

I would like to generate a random covariance matrix with variances in certain range.

How can it be done? (In R if possible)

I tried to generate a lower triangular matrix $L$ where the diagonal $D = \sqrt{V}$, where $V$ is the vector of variances. The problem lies with the rest of the values that do not lie on the diagonal. I do not know how to generate them in order to get at the end a meaningful covariance matrix. Finally, I would just do $C = LL^T$ (Cholesky) in order to get a positive definite matrix with the diagonal being $V$.

• how big a matrix you want? generating random covariance matrix is not that easy as a random matrix is very unlikely to have cov. matrix (grows really fast in number of assets) properties (positive semi definitness etc...) there are methods though. – Jan Sila Jan 9 '17 at 14:49
• Also it is not clear what should be random in your covariance matrix: the marginal variances (variance vector) or the linear dependence structure (correlation matrix) ? Indeed you say you want variances in a certain range but seem to use a fixed vector $V$? – Quantuple Jan 9 '17 at 17:43

A useful decomposition is, in R's matrix notation, V = S %*% C %*% S, in which S is a matrix with the standard deviations on the main diagonal and zeros elsewhere, and C is the correlation matrix. (See this note on Matrix Multiplication with Diagonal Indices.)

To get a meaningful V, you need to have C positive (semi)-definit. A simple way to achieve this is to make the correlation a positive constant.

n <- 5  ## number of assets
C <- array(0.5, dim = c(n, n))
diag(C) <- 1


For more variation, an approach that I have used is to sample correlations from a reasonable range. Then, of course, there is no guarantee that C is positive semi-definit, but you can repair it. See, for instance, the function repairMatrix in package NMOF.

I haven't heard of a method to do it your way. Usually, you start with covariance matrix and do Cholesky in order to be able to generate random draws from the multinomial normal distribution with given covariance matrix. Maybe that is what you want?

In any case, if you need precisely specify the variances, see:

Hirschberger, M., Y. Qi, & R. E. Steuer (2007): “Randomly generating portfolio-selection covariance matrices with specified distributional charac- teristics.” European Journal of Operational Research 177(3): pp. 1610–1625.

But they have to be quite specific and I wasn't able to get their algorithm working.

But more suitable I reckon is Higham's Nearest PD (implemented in R in Matrix package, function nearPD.

Higham, N. J. (2002): “Computing the nearest correlation matrix—a problem from finance.” IMA journal of Numerical Analysis 22(3): pp. 329–343.

It is not entirely clear to me what you really want but the following approach might help.

I assume you can generate (samples of) "variances in a certain range". So let $\sigma_1^2,\ldots,\sigma_n^2$ be an (instance of) such variances.

Your problem then is to find a way to generate random symmetric matrices with eigenvalues $\sigma_1^2,\ldots,\sigma_n^2$. According to the spectral theorem a real n-by-n matrix $C$ is positive definite with such eigenvalues if and only if it allows orthogonal diagonalisation, i.e. the factorisation

$$C = Q D Q^T$$

where $D=\text{diag}(\sigma_1^2,\ldots,\sigma_n^2)$ is a diagonal and $Q$ a n-by-n orthogonal matrix.

Since you know $D$ the only thing you need to do is sample orthogonal matrices. This can be done in R using rortho from the package pracma.