Skip to content

Instantly share code, notes, and snippets.

@laholmes
Created December 19, 2016 15:16
Show Gist options
  • Save laholmes/12b2cbc89b24e70cf082980dc4f51ebb to your computer and use it in GitHub Desktop.
Save laholmes/12b2cbc89b24e70cf082980dc4f51ebb to your computer and use it in GitHub Desktop.
cointegration test + cross hedging
library('zoo')
library('urca')
prices <- read.zoo('./priceData.csv', sep=',', FUN = as.yearmon, format='%Y-%m', header=TRUE)
# taking into account short term behaviour, derive the minimum variance hedge by fitting
# a linear model that explains changes in B prices by changes in A prices
# beta coefficient of the regression is the optimal hedge ratio
# intercept is zero as no cash holdings
simple_mod <- lm(diff(prices$B) ~ diff(prices$A) + 0)
summary(simple_mod)
# if hedge ratio <1, not a perfect hedge - the resulting hedged portfolio is still risky
# try to improve on hedge ratio by using existing long-run relationship between levels
# plot to get initial view on existence of such a relationship
plot(prices$B, main='A and B prices', xlab='Date', ylab='USD')
lines(prices$A, col='red')
# using Engle and Granger's two-step estimation technique for cointegration
# first test both time series for a unit root (non-stationarity), using augmented
# Dickey-Fuller test
b_adf <- ur.df(prices$B, type='drift')
summary(b_adf)
# the null hypothesis of non-stationarity - time series contains a unit root, cannot be
# rejected at the 1% level id test statistic is not < 1% critical val
# same is true for A prices?
a_adf <- ur.df(prices$A, type='drift')
summary(a_adf)
# estimate the static equilibrium model + test residuals for a stationary
# time series using augmented dickey fuller test
# different critical values must be used as the series is an estimated one
mod_static <- summary(lm(prices$B ~ prices$A))
error <- residuals(mod_static)
error_cadf <- ur.df(error, type='none')
summary(error_cadf)
# if test stat < 1% crit value -> reject null hyp of non-stationarity
# -> we have discovered two cointegrated variables, and can proceed
# with specification of an error-correction model (ECM)
# ECM represents a dynamic model of how (and how fast) the system moves back
# to the static equilibrium estiamted earlier
db <- diff(prices$B)
da <- diff(prices$A)
error_lag <- lag(error, k=-1)
mod_ecm <- lm(db ~ da + error_lag + 0)
summary(mod_ecm)
# by taking into account existence of long-run relationship between
# A and A prices (cointegration), hedge ratio is now slightly higher
# coefficient of the error term is negative - large deviations between the two
# prices are going to be corrected and prices move closer to their
# long-run stable relationship
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment