Suppose I have three assets $x_1,x_2,x_3$ in a portfolio with weights $W=\begin{bmatrix} w_1 \\ w_2 \\ w_3 \end{bmatrix} $, expected returns $R=\begin{bmatrix} \mu_1 \\ \mu_2 \\ \mu_3 \end{bmatrix}$, and a covariance matrix $V$.

The expected return of my portfolio is $\mu_p=W^TR$ and the variance of my portfolio is $\sigma^2_p=W^TVW$.

I would like to run Monte Carlo simulations on my portfolio using a normal distribution.

I can do this either by:

  1. Sampling from the distribution of portfolio returns $N(\mu_p,\sigma^2_p)$.
  2. Sample from the three individual asset returns and use those three returns to compute my overall portfolio return.

First, how would I accomplish the second approach (would I be sampling from a multivariate normal distribution)?

Second, are these two approaches equivalent as long as I assume that the weights $W$ of my portfolio remain the same?


2 Answers 2


For the first case, you would directly sample $n$ random normals $x$ and compute: $$R^p_i = \mu_p + \sigma_p x_i, i \in [1,n]$$

For the second case, you can sample $n$ x $3$ independent normals, compute the Cholesky decomposition matrix $C$ of $V$, which is the matrix $C$ such that $V=C^t C$, and get $n$ samples of vectors $X$ of size 3.

The return $R_i$ for random draw $i$ is given by: $$R_i = \mu_p + C . X_i, i \in [1,n]$$ You can check for high values of $n$ the convergence towards the limit values: $$E(R_i) = R$$ $$Cov(R_i) = V$$ The portfolio return is then computed as: $$R^p_i = W.T R_i$$ and you can check it converges towards the same mean and variance $\mu_p$, $\sigma_p^2$ for a large enough $n$.

The two approaches are mathematically equivalent as a linear combination of independent normals is normally distributed. This works so long as the random normal variables generated are iid gaussian normals.

With numpy, iid normals can be generated with np.random.normal. As pointed out below, np.random.multivariate_normal can be used to generate the multivariate gaussian vector.

  • 1
    $\begingroup$ How does this compare to using docs.scipy.org/doc/numpy-1.15.1/reference/generated/…? $\endgroup$
    – cpage
    Commented Nov 23, 2018 at 16:16
  • $\begingroup$ good question from @cpage on a 5x5 historical covariance matrix, I get 0.27s for 1e6 samples from np.random.multivariate_normal and 5.3s using np.random.normal with a loop in python. The samples have similar statistics but different values. $\endgroup$
    – Sebapi
    Commented Nov 24, 2018 at 9:52
  • $\begingroup$ why use np.random.normal to generate random i.i.d. variables, when financial returns are non-i.i.d. due to serial correlation? Is there something about the asker's two cases that lets us neglect this empirical fact? $\endgroup$
    – develarist
    Commented Jul 13, 2020 at 2:42
  • $\begingroup$ what added value in terms of portfolio analysis does looking at portfolio/asset return distributions have, which are a collection of datapoints in vector form, versus looking at only their moments, $\mu$ and $\sigma$, which are scalars that summarize the distribution? In other words, what can you do with a distribution for portfolios that you can't already do with just their moments? $\endgroup$
    – develarist
    Commented Jul 17, 2020 at 10:58
  • $\begingroup$ @develarist, specifying the mean and variance determines the distribution if one assumes that it is gaussian. Note that the $n$ dimensional multivariate distribution requires an expectation vector and a covariance matrix. The latter looks more like a symetric matrix than a vector. $\endgroup$
    – Sebapi
    Commented Nov 15, 2020 at 12:09

Basically what @sebapi said. "The two approaches are equivalent so long as the random normal variables generated are iid gaussian normals."

Q: How does this compare to using docs.scipy.org/doc/numpy-1.15.1/reference/generated/…?

A: You might use scipy.stats.multivariate_normal (rv = multivariate_normal(mean=None, cov=1, allow_singular=False))


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.