This R session will illustrate pairs trading or statistical arbitrage.

(Useful R links: Cookbook R, Quick-R, R documentation, CRAN, METACRAN.)

Cointegration tests

There is a very convenient package, egcm, that computes the Engle-Granger cointegration test and many other unit-root tests. In particular, given two series \(x(t)\) and \(y(t)\), it searches for parameters \(\alpha\), \(\beta\), and \(\rho\) such that

\[ y(t) = \alpha + \beta x(t) + r(t)\\ r(t) = \rho r(t-1) + \epsilon(t) \] where \(r(t)\) is the residual and \(\epsilon(t)\) the innovation. If \(|\rho|<1\), then \(x(t)\) and \(y(t)\) are cointegrated (i.e., \(r(t)\) doesn’t contain a unit root). Of course the difficulty is in assessing exactly how much smaller than 1 the value of \(|\rho|\) has to be; this is the task of the unit-root test. The package urca contains more general models for cointegration. Perhaps the most famous example of a unit-root test is the Augmented Dickey-Fuller (ADF) test, which considers as null hypothesis that a unit root is pressent and as alternative hypothesis that the series is stationary (so a small \(p\)-value means indication of strong stationarity).1

Another interesting quantity to measure mean-reversion is the half-life, defined as the time it takes for the spread to mean-revert half of its distance after having diverged from the mean of the spread.

We now use the package egcm to check the cointegration of several illustrative examples:

library(quantmod)
library(egcm)  #install.packages("egcm")
egcm.set.default.pvalue(0.01)

SPY vs IVV

SPY and IVV are oth ETF’s that track the S&P 500 and obviously they are cointegrated:

SPY_prices <- Ad(getSymbols("SPY", from = "2013-01-01", to = "2013-12-31", auto.assign = FALSE))
IVV_prices <- Ad(getSymbols("IVV", from = "2013-01-01", to = "2013-12-31", auto.assign = FALSE))
plot(cbind(SPY_prices, IVV_prices), legend.loc = "topleft", main = "ETF prices")