Trading Autocorrelation?

[This article was first published on Quintuitive » R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Markets are very smart in absorbing and reflecting information. If you think otherwise, try making money by trading. If you are new to it, make sure you don’t bet the house.

In other words, markets are efficient. At least most of the time. So then why people trade? The general believe is that there are windows during which prices of certain assets are inefficient. Thus, there are opportunities to make money. Is the presence of autocorrelation one such opportunity? Let’s find out.

To keep things simple, we will use the standard R acf function to compute the autocorrelation.

# Note: We use adjusted close - it's unrealistic to expect anything from actual close in the
# presence of dividends
spy.rets = ROC(Ad(spy),na.pad=F)
aa = acf(tail(spy.rets,500),main="ACF computed over the last 500 days")
# [1]  1.000000000  0.051116484 -0.037469705 -0.010014871 -0.126667484 -0.004113005

This will produce the following chart:
It shows the autocorrelation coefficients at different lags. The first lag is the correlation of the series with itself (lag 0), and, it’s always 1. The second value (0.051116484) is the correlation of the series with the series lagged by one.

The two dashed lines are the confidence intervals for the lags. They are of special interest since we are going to use them to decide when there is significant autocorrelation. How are they computed? To find the answer, I had to look at the acf’s code:

# xx is the series, conf.level is the confidence level - think 0.95 for instance
conf = qnorm((1 + conf.level)/2)/sqrt(sum(!

The above is nothing else but computing confidence intervals for normal (0,1) distribution. It still puzzles me (I couldn’t find an answer quickly when I thought about it) why the correlation coefficients at different lags are distributed normally in (0,1), but that’s irrelevant.

The last question is how to trade extreme autocorrelation – do we bet that the autocorrelation persists, or do we bet that the autocorrelation fades? There are two variables here: the sign of the correlation and the sign of the last day return. A table is helpful.

Correlation Sign Return Sign Persisting Signal Fading Signal
1 1 1 -1
1 -1 -1 1
-1 1 -1 1
-1 -1 1 -1

My gut tells me to go with the fading – markets are efficient, especially this one. So, let’s run a quick backtest, putting all this mumbo-jumbo into code.

high.acf = function(xx,conf.level=0.95,lag=1) {
   aa = acf(xx,plot=F)
   conf = qnorm((1 + conf.level)/2)/sqrt(sum(!
   if(abs(aa$acf[lag+1,1,1]) > conf) sign(aa$acf[lag+1,1,1]) else 0

backtest.acf = function(rets, n=21, conf.level=0.95, lag=1, fade=F, dates="2004/2013") {
   aa = na.trim(rollapplyr(rets, width=n+lag, FUN=high.acf, conf.level=conf.level, lag=lag))
   bb = merge(rets, aa, all=F)
   ind = sign(bb[,1]*bb[,2])
   if(fade) ind = -ind
   cc = merge(rets, lag.xts(ind), all=F)
   dd = cc[,1]*cc[,2]
   strat = dd[dates] = NROW(which(as.numeric(strat) > 0, arr.ind=T))
   n.trades = NROW(which(as.numeric(strat) != 0, arr.ind=T))
   str = paste(round(*100,2), "% [",, "/", n.trades, "]", sep="")

# About 3 (trading) months of history
backtest.acf(spy.rets, dates="2004/2013", fade=T, n=63)
# [1] "54.88% [45/82]"

The percentage looks ok, but the sample is small (only 82 opportunities over 10 years). Is it possible that there is some opportunity here – too early to tell. Certainly worth looking further though, IMO.

The post Trading Autocorrelation? appeared first on Quintuitive.

To leave a comment for the author, please follow the link and comment on their blog: Quintuitive » R. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)