Created
December 19, 2016 15:16
-
-
Save laholmes/12b2cbc89b24e70cf082980dc4f51ebb to your computer and use it in GitHub Desktop.
cointegration test + cross hedging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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