Take the 2-minute tour ×
Quantitative Finance Stack Exchange is a question and answer site for finance professionals and academics. It's 100% free, no registration required.

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?)

share|improve this question
    
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. –  SRKX Apr 20 '11 at 8:33
    
Thanks for the pointer, I wasn't aware of th QRMlib procedure, indeed I am using rmnorm from the mnormt package. –  Owe Jessen Apr 20 '11 at 9:05
2  
honestly, a few comments in your code would be most welcomed... –  SRKX Apr 20 '11 at 10:05
2  
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)? –  bill_080 Apr 20 '11 at 17:01
    
I replicated the equicorr-function myselfs, sorry for not including. I updated the "current" code. –  Owe Jessen Apr 20 '11 at 20:05
show 3 more comments

2 Answers

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.

share|improve this answer
add comment

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).

share|improve this answer
    
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? –  Owe Jessen Apr 29 '11 at 8:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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