17
$\begingroup$

I'll start this off with a rather broad question: I am trying to simulate returns of a large number of assets within a portfolio of different classes - equity and fixed income in a first step, say 100 stocks and 100 bonds. The main target is to preserve something similar to a realistic correlation structure within the returns. What would be a good way to go about it?

My first idea was to estimate the correlation between the classes, draw multivariate normal returns (yes, I know, but if you have better ideas, I'd like to hear them) based on historical mean, sd and correlation, and then replicate the two baseline return series with random errors, say something like (pseudo R code, I think it's clear what I mean)

require(mnormt)
n <- 100 # number of assets
m <- 1000 # days of simulated data
means <- apply(cbind(equity,bond),2,mean)
Sigma <- cov(cbind(equity,bond))
sim.returns <- rmnorm(1000,means,Sigma)
sim.equities <- matrix(sim.returns[,"equity"]*rnorm(m*n,mean=1,sd=0.5),ncol=n)
sim.bonds <- matrix(sim.returns[,"bond"]*rnorm(m*n,mean=1,sd=0.2),ncol=n)

Any suggestions, improvements or other comments wellcome - how would you do it, or do it better?

Update: This is were I am now (as of 2011-04-29):

require(quantmod)
rets.dax <- dailyReturn(GDAXI)
(DBCNumber <- 100)
(DBCNames <- as.character(paste("DBC",1:DBCNumber,sep="_")))
(DBCBetas <- runif(DBCNumber, min=0.8,max=1.5)) # seeding Betas
DBCErrors <- matrix(rnorm(nrow(rets.dax)*DBCNumber,sd=0.01),ncol=DBCNumber) #seeding errors
DBCReturns <- matrix(rep(NA,nrow(rets.dax)*DBCNumber),ncol=DBCNumber)
#simulating returns with the betas and errors
for(i in 1:DBCNumber){DBCReturns[,i] <- rets.dax*DBCBetas[i]+DBCErrors[,i]} 
DBCReturns <- xts(DBCReturns,order.by=index(rets.dax))
colnames(DBCReturns) <- DBCNames
DBCIndizes <- xts(apply(DBCReturns+1,2,cumprod),order.by=index(rets.dax)) #calculating prices

cols <- heat.colors(DBCNumber)
chart.RelativePerformance(DBCReturns,rets.dax,colorset=cols, lwd=1)

I am quite happy now with the equity returns, but do you have suggestions for bond returns (data sources, can I copy the approach from equities?)

$\endgroup$
8
  • $\begingroup$ maybe just mention that the "trick" you're using here comes from the rmnorm function from QRMlib. It could be understood as a typo. You could also assume the dynamics of your assets and "discretize" them to simulate paths; your covariance becomes a paremeter of the dynamics and you only use brownian motions. $\endgroup$
    – SRKX
    Commented Apr 20, 2011 at 8:33
  • $\begingroup$ Thanks for the pointer, I wasn't aware of th QRMlib procedure, indeed I am using rmnorm from the mnormt package. $\endgroup$
    – Owe Jessen
    Commented Apr 20, 2011 at 9:05
  • 2
    $\begingroup$ honestly, a few comments in your code would be most welcomed... $\endgroup$
    – SRKX
    Commented Apr 20, 2011 at 10:05
  • 2
    $\begingroup$ I'm a little confused. As your code stands now, you're using functions equicorr() and rmnorm(). Doesn't equicorr() come from the QRMlib package? But, if you load QRMlib, doesn't that change the usage of rmnorm() to coincide with the rmnorm() in QRMlib, not package mnormt (as shown here)? $\endgroup$
    – bill_080
    Commented Apr 20, 2011 at 17:01
  • $\begingroup$ I replicated the equicorr-function myselfs, sorry for not including. I updated the "current" code. $\endgroup$
    – Owe Jessen
    Commented Apr 20, 2011 at 20:05

3 Answers 3

4
$\begingroup$

I have a few thoughts, but no real answers :).

  • You take the returns from the DAX, which isn't normal, then make it normal and apply normal noise to it. It seems that you could be slightly better off just applying the noise to the original, non-normalized DAX.

  • Have you considered the t-distribution? There are multivariate t-distribution packages in R (e.g., mnormt)

  • The normal, skinny tails really show in the plot. I would expect that a few should have huge returns or losses.

From this I have two suggestions:

  • Why not just pull down real stock data from Yahoo via QuantMod? Do any of the packages have scripts for pulling all tickers?

  • Why not assign a $\beta$ to each simulated equity (and bond)? As long as the $\beta$s sum to one, it should be OK (although then you'll be vulnerable to your assumptions about the distribution of $\beta$ -- using real data frees you of this, although even then you're vulnerable to time period).

$\endgroup$
1
  • $\begingroup$ Got back to this. As you can see, I heeded your advice of seeding betas. Are there any suggestions with regard to the range of possible betas and errors? $\endgroup$
    – Owe Jessen
    Commented Apr 29, 2011 at 8:10
3
$\begingroup$

I think your best best is going to be some kind of blocked bootstrap sampling using real market data. If you use a pure simulation approach to "make up" a dataset, there's a significant probability that you're going to end up with a mis-specified model.

For starters, you can use the R package quantmod to pull in daily stock market data and calculate returns, and the tsbootstrap function in the tseries package will let you construct hypothetical return series with some basis in reality.

$\endgroup$
0
$\begingroup$

To preserve the dependence structure of market returns the easiest way is to do a resampling (bootstrap): Take your returns and normalize each asset by its daily standard deviation. Then at each step draw a uniformly chosen random date in your sample and use the vector of normalized returns from that date as your IID noise. This procedure preserves the dependence structure of the returns without assuming any specific distribution. Not just the correlation but the also the tail dependence

You can combine this with any distributional model or volatility model (GARCH, SV, etc) for each asset.

$\endgroup$

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.