Title

This is an R Markdown document. Markdown is a simple formatting syntax for authoring web pages (click the Help toolbar button for more details on using R Markdown).

When you click the Knit HTML button a web page will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

You can also embed plots, for example:

plot(cars)

plot of chunk unnamed-chunk-1

Using Correlations to determine the market regime switching

blog shows a market timing strategy which determines the market switching point. The market is represented by S&P 500. The strategy calculates the correlation matrix changes of the 500 stocks within S&P. The performance of this strategy looks quite promising.

However, to download the historical data of all the 500 stocks and calculate the correlation matrix are not a trivial tasks, not mentioning the changes of the 500 stocks included in SPX index in the past. Therefore, an easy substitute of the 500 stocks will be the sector ETFs which represents the 9 different sectors of the US market.

We are using SPDR sector ETFs (XLE, XLF and etc) and SPY (the SPDR ETF of the S&P 500 index).

Data D

We use quantmod to download the time series of SPY and the other 9 sector ETFs.

library(xts)
## Warning: package 'xts' was built under R version 3.0.2
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following object is masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(zoo)
library(Quandl)
## Warning: package 'Quandl' was built under R version 3.0.2
library(quantmod)
## Loading required package: Defaults
## Loading required package: TTR
## Version 0.4-0 included new data defaults. See ?getSymbols.

load(file = "etf.RData")

Correlations

Now first calculate the returns of SPY and ETFs, and then calculate the rolling correlation matrix

returns = log(lag(data_etf, 1)/data_etf)
returns = returns[2:nrow(returns)]

# Calculate the average correlations
vcorr <- function(x) {
    corr = cor(x)
    n = ncol(x)
    nr = n * (n - 1)
    vc = (sum(corr) - n)/2
    return(vc)
}


rsize = 60
for (i in 1:nrow(returns)) {
    if (i < rsize) 
        data_all$vcorr[i] = 0 else data_all$vcorr[i] = vcorr(returns[(i - rsize + 1):i])
}

vcorr_ma <- rollmean(data_all$vcorr, 100)


par(mfrow = c(2, 1), oma = c(0, 0, 0, 0))
plot(data_all$SPY)
par(new = TRUE)
plot(vcorr_ma)
# lines(data_all$vcorr, col='green')

plot of chunk unnamed-chunk-3

Prediction Power of Correlation

signal <- (data_all$vcorr < (0.9 * vcorr_ma))
signal1 <- (data_all$vcorr > (1.1 * vcorr_ma))

plot(data_all$SPY)
points(data_all$SPY[signal], col = "green", pch = 20)
points(data_all$SPY[signal1], col = "red", pch = 1)

plot of chunk unnamed-chunk-4