{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Vector Error Correction Model (VECM): Applications In Finance"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"
\n",
"\n",
"### Notebook by [Marco Tavora](https://marcotavora.me/)\n",
"\n",
"## Table of contents\n",
"\n",
"1. [Introduction](#Introduction)\n",
"2. [Installing Packages](#Installing-Packages)\n",
"3. [Johansen Test for Cointegration](#Johansen-Test-for-Cointegration)\n",
"3. [Fitting the VECM](#Fitting-the-VECM)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"[[go back to the top]](#Table-of-contents)\n",
"\n",
"From [Wikipedia](https://en.wikipedia.org/wiki/Error_correction_model#VECM):\n",
"\n",
"> The Engle–Granger approach as described above suffers from a number of weaknesses. Namely it is restricted to only a single equation with one variable designated as the dependent variable, explained by another variable that is assumed to be weakly exogeneous for the parameters of interest. It also relies on pretesting the time series to find out whether variables are I(0) or I(1). These weaknesses can be addressed through the use of Johansen's procedure. Its advantages include that pretesting is not necessary, there can be numerous cointegrating relationships, all variables are treated as endogenous and tests relating to the long-run parameters are possible. \n",
"\n",
"VECM models add error correction terms to the vector autoregression (VAR) model. Using simple matrix algebra,\n",
"the model can be written as follows:\n",
"\n",
"$$\\,\\left[ {\\begin{array}{*{20}{c}}\n",
"{\\Delta {y_{1,t}}}\\\\\n",
"{\\Delta {y_{2t}}}\n",
"\\end{array}} \\right] = \\left[ {\\begin{array}{*{20}{c}}\n",
"{{\\gamma _{01}}}\\\\\n",
"{{\\gamma _{02}}}\n",
"\\end{array}} \\right] + \\left[ {\\begin{array}{*{20}{c}}\n",
"{{\\alpha _1}}\\\\\n",
"{{\\alpha _2}}\n",
"\\end{array}} \\right]\\left[ {{\\beta _0}\\,\\,\\,{\\beta _1}\\,\\,\\,{\\beta _2}} \\right]\\left[ {\\begin{array}{*{20}{c}}\n",
"1\\\\\n",
"{{y_{1,t - 1}}}\\\\\n",
"{{y_{2,t - 1}}}\n",
"\\end{array}} \\right] + \\left[ {\\begin{array}{*{20}{c}}\n",
"{{\\gamma _{11}}}&{{\\gamma _{21}}}\\\\\n",
"{{\\gamma _{12}}}&{{\\gamma _{22}}}\n",
"\\end{array}} \\right]\\,\\,\\left[ {\\begin{array}{*{20}{c}}\n",
"{\\Delta {y_{1,t - 1}}}\\\\\n",
"{\\Delta {y_{2,t - 1}}}\n",
"\\end{array}} \\right] + \\left[ {\\begin{array}{*{20}{c}}\n",
"{{\\gamma _{31}}}&{{\\gamma _{41}}}\\\\\n",
"{{\\gamma _{32}}}&{{\\gamma _{42}}}\n",
"\\end{array}} \\right]\\,\\,\\left[ {\\begin{array}{*{20}{c}}\n",
"{\\Delta {y_{1,t - 2}}}\\\\\n",
"{\\Delta {y_{2,t - 2}}}\n",
"\\end{array}} \\right] + \\left[ {\\begin{array}{*{20}{c}}\n",
"{{\\nu _{1,t}}}\\\\\n",
"{{\\nu _{2,t}}}\n",
"\\end{array}} \\right]$$\n",
"\n",
"Following [this excellent blog post](http://blog.mindymallory.com/2018/02/basic-time-series-analysis-a-drunk-and-her-dog-explain-cointegration-and-the-vecm-model/) I will choose $y_1$ and $y_2$ to be the following time series:\n",
"\n",
"- SPY (the S&P 500 exchange traded fund)\n",
"- SHY (iShares 1-3 year Treasury Bond) prices. \n",
"\n",
"If both series are cointegrated, this information must included in the model. This is done introducing, as mentioned above, error correction terms:\n",
"\n",
"$${\\alpha _i}({\\beta _0}\\, + {\\beta _1}{y_{1,t - 1}}\\, + {\\beta _2}{y_{2,t - 1}}),\\,\\,\\,\\,\\,i = 1,2$$\n",
"\n",
"where \n",
"\n",
"$$({\\beta _0}\\, + {\\beta _1}{y_{1,t - 1}}\\, + {\\beta _2}{y_{2,t - 1}}),\\,\\,\\,\\,\\,i = 1,2$$\n",
"\n",
"corresponds to the long-run. If in the long-run the last equation is zero we have the folowing relation:\n",
"\n",
"$$\\,{y_{2,t - 1}} = - ({\\beta _0}/{\\beta _2})\\, - ({\\beta _1}/{\\beta _2}){y_{1,t - 1}}$$\n",
"\n",
"Hence, the $\\beta$s we obtain after fitting the VECM inform us about the equilibrium relationship between the time series. When the two series deviate from equilibrium, the $\\alpha$s \"push them back\".\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Installing Packages\n",
"[[go back to the top]](#Table-of-contents)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# install.packages('ggplot2')\n",
"# install.packages('xts')\n",
"# install.packages('quantmod')\n",
"# install.packages('broom')\n",
"# install.packages('tseries')\n",
"# install.packages(\"kableExtra\")\n",
"# install.packages(\"knitr\")\n",
"# install.packages(\"vars\")\n",
"# install.packages(\"urca\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To load the data we will use the library `quantmod` which contains the function `getSymbols`. From the [documents](https://www.rdocumentation.org/packages/quantmod/versions/0.4-13/topics/getSymbols)\n",
"\n",
"> getSymbols is a wrapper to load data from various sources, local or remote.\n",
"\n",
"In our case we will load data from Yahoo Finance."
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"rm(list=ls()) \n",
"library(tseries)\n",
"library(dynlm)\n",
"library(vars)\n",
"library(nlWaldTest) \n",
"library(lmtest)\n",
"library(broom) \n",
"library(car)\n",
"library(sandwich)\n",
"library(knitr)\n",
"library(forecast) "
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"