# Generate random multivariate values from empirical data

I'm working on a Monte Carlo function for valuing several assets with partially correlated returns. Currently, I just generate a covariance matrix and feed to the the rmvnorm() function in R. (Generates correlated random values.)

However, looking at the distributions of returns of an asset, it is not normally distributed.

This is really a two part question:
1) How can I estimate some kind of PDF or CDF when all I have is some real-world data without a known distribution?

2) How can I generate correlated values like rmvnorm, but for this unknown (and non-normal) distribution?

Thanks!

The distributions do not appear to fit any known distribution. I think it would be very dangerous to assume a parametric and then use that for monte carlo estimation.

Isn't there some kind of bootstrap or "empirical monte carlo" method I can look at?

(1) It's the CDF you'll need to generate your simulated time-series. To build it, first histogram your price changes/returns. Take a cumulative sum of bin population starting with your left-most populated bin. Normalize your new function by dividing by the total bin population. What you are left with is a CDF. Here is some numpy code that does the trick:

# Make a histogram of price changes

counts,bin_edges = np.histogram(deltas,numbins,normed=False) # numpy histogram

# Make a CDF of the price changes

n_counts,bin_edges2 = np.histogram(deltas,numbins,normed=True)
cdf = np.cumsum(n_counts)  # cdf not normalized, despite above
scale = 1.0/cdf[-1]
ncdf = scale * cdf


(2) To generate correlated picks, use a copula. See this answer to my previous question on generating correlated time series.

Regarding the first question, you might consider resampling your data. There would be a problem in case your data were correlated over time (rather than contemporaneously correlated), in which case you would need something like a block bootstrap. But for returns data, a simple bootstrap is probably fine.

I guess the answer to the second question is very much dependent on the target distribution.

The answer to the first question is that you build a model. In your case this means choosing a distribution and estimating its parameters.

When you have the distribution you can sample from it using Gibbs or Metropolis algorithms.

On the side note, do you really need to sample from this distribution? Usually the interest is in some characteristic of the distribution. You can estimate it using empirical distribution via bootstrap, or again build a model for this characteristic.

• I'm interested in sampling possible returns for a given asset. Since the distribution isn't normal AND the assets are correlated over time, that creates a challenge in choosing a distribution. I'm exploring monte carlo methods for portfolio optimization. – Noah Dec 24 '10 at 22:05
• @Noah, have you considered various stochastic volatility models, such as GARCH? – mpiktas Dec 25 '10 at 14:44
• I have looked at GARCH models. However, GARCH wouldn't solve this problem. I'm looking at generating correlated random samples from multiple time series. Random multi-variate norm sample work, but they require the assumption that returns are normally distributed and in this case, they are not. – Noah Dec 27 '10 at 9:02
• @Noah, how about multivariate GARCH? Each individual series is GARCH with innovations from multivariate normal with non-diagonal covariance matrix. Then the returns will not have normal distribution, but they will be correlated. – mpiktas Dec 28 '10 at 9:39

I'm with @mpiktas in that I also think you need a model.

I think the standard method here would be to estimate a copula to capture the dependence structure between the different assets and use e.g. skew-normal- or t-distributed marginal distributions for the different assets. That gives you a very general model class (more general that assuming e.g. a multivariate t-distribution) that is pretty much the standard for your kind of task (e.g. I think Basel II requires financial institutions to use copula-methods to estimate their VaR). There's a copula package for R.

A possible answer to the first part of the question using R... using the ecdf() function

# simulate some data...
N <- 1000
fdata <- c( rnorm(N %/% 2, mean=14), rnorm(N %/% 2, mean=35))

# here's the Empirical CDF of that data...
E1 <- ecdf(fdata)
plot(E1)

# now simulate 1000 numbers from this ECDF...
ns <- 1000
ans <- as.numeric(quantile(E1, runif(ns)))
hist(ans,pro=T,nclass=113,col='wheat2')

• This only applies to univariate data. – Stéphane Laurent Aug 28 '15 at 12:14