5 weeks ago we took a look at the rising volatility in the (US) equity markets via a time-series threshold model for the VIX. The estimate suggested we are crossing (or crossed) to the more volatile regime. Here, taking somewhat different Hidden Markov Model (HMM) approach we gather more corroboration (few online references at the bottom if you are not familiar with HMM models. The word hidden since the state is ‘invisible’).
We can again use contributed free R-code, the depmixS4 package written by Maarten Speekenbrink and Ingmar Visser who I recently met at the Amsterdam R-meetup group where he gave a talk about the package. RHmm package is another option.
A text book example for estimating Bull-Bear regime switching uses only the return series. However, we can make a sharper model if we add the VIX index as an additional variable which helps to determine the regime. The advantage is that a drawdown can be better classified as being in the bear regime, if it also accompanied by a high levels implied volatility. As oppose to a drawdown which is a natural correction in a bull market.
We estimate the HMM once without the VIX as additional explanatory variable and once with. The equation for the returns in both cases is that they are random-walk (unpredictable), so VIX only enters to the equation which helps determine the state in which we are in. The way it is done is using logistic regression with one of the regimes as ‘base’, so the usual ‘transition matrix’ is not that easy to interpret anymore as in the case where we don’t have any explanatory variables.
Here is the result, we see (1) a sharper classification with the VIX making sense and (2) oh, we are bear now.
You can click on the figure for better clarity.
Code for reproduction
snp <- getYahooData("^GSPC",start=19990101,end=20141016,freq="daily")
vix <- getYahooData("^VIX",start=19990101,end=20141016,freq="daily")
time <- as.Date(substr(index(snp),1,10))[-1] # get the time index and remove first obs
vixp <- apply(vix[,-5],1,mean)[-1] # average daily price (sort of..) # remove first obs
# convert to returns (that is why we removed first obs before
snpp <- as.numeric(apply(snp[,-5],1,mean)) # average daily price (sort of..)
TT <- length(snpp)
ret <-100*( snpp[2:TT]/snpp[1:(TT-1)] - 1) # convert to daily returns
plott(ret,vixp,ret=F,ty="p",xlab="VIX",main="Market returns (%) on VIX")
mod <- depmix(ret ~ 1, data=data.frame(ret=ret,vixp=vixp), transition=~1,nstates=2, family=gaussian())
mod2 <- depmix(ret ~ 1, data=data.frame(ret=ret,vixp=vixp), transition=~vixp,nstates=2, family=gaussian())
# mod2 <- depmix(ret ~ vixp, data=data.frame(ret=ret,vixp=vixp), nstates=2)
modfit <- fit(mod,verbose=T)
modfit2 <- fit(mod2,verbose=T)
summary(modfit, which = "transition")
summary(modfit2, which = "transition")
trans1 <- as.matrix(posterior(modfit))
trans2 <- as.matrix(posterior(modfit2))
## The Figure
col1 <- rgb(1,0,0,1/4)
col2 <- rgb(0,1,0,1/4)
plott(scale(snpp[-1],scale=T)/3,time,ret=F,ty="l",main="(scaled) SNP with superimposed posterior probabilities of bear regime")
plott(trans2[,3],time,ty="l",add=T,col=col2) # the other regime is base
legend('bottomright',legend=c("model without VIX","Model with VIX"),cex=1.3,