RATS 10.1
RATS 10.1

This is a replication for the work in T. H. Lee(1994), which estimates a set of VECM-GARCH-X models on spot and forward exchanges rates for several countries.


The raw data are spot and forward exchange rates for seven countries (UK, West Germany, Japan, Canada, France, Italy and Switzerland). The models are bivariate VECM's for each country separately, with the assumption that log spot and log forward are cointegrated with log f - log s being the cointegrating relationship. This is tested for each country with Dickey-Fuller tests on log spot, log forward and the difference, with the expectation that the first two will have unit roots and the last will be stationary—this is confirmed by the data.


The paper estimates three models given the VECM structure: a regular VECM with homoscedastic residuals, a BEKK model, and a BEKK model with an "X" regressor. The chosen BEKK form for is the diagonal and the chosen form for the "X" is separate terms.

 

The data series are named fxx and sxx where xx is a two-letter suffix representing each country (such as wg for West Germany). The analysis is done in a loop over the country suffixes, based upon the following pseudocode:

 

dec label country

dofor country = suffix

   *

   * create transformed data for spot and forward for <<country>>

   * do unit root tests

   * select lag length for VECM model

   * create VECM model

   * estimate VECM without GARCH process

   * estimate VECM with GARCH process

   * estimate VECM with GARCH-X process

   *

end dofor country



This pulls out the series handles for the forward and spot prices for the country being analyzed.

 

   compute sforward=%s("f"+country)

   compute sspot   =%s("s"+country)

 

The empirical results in the paper use just log(x) in the transformation. Using 100 log(x) improves the ability to estimate by model by changing the scale on the variance constants. The only other things that will be affected are the CONSTANT in the mean model, and the values of the log likelihoods and regression criteria—the other GARCH coefficients, the lag coefficients in the mean model, the likelihood ratio statistics and the ordering of the models by information criteria (in short, everything that actually matters) will be unaffected. You can (closely) replicate the actual results by changing the 100* to 1*.


Because sforward and sspot are handles to series (not the series themselves), we need the {0} notation to get the current value of the series.

 

   set forward  = 100*log(sforward{0})

   set spot     = 100*log(sspot{0})

   set z        = forward-spot


This does Dickey-Fuller tests on the log spot, log forward and the difference. Expected results are unit roots on the first two and not on the difference.

 

   @dfunit(lags=10,method=bic) spot

   @dfunit(lags=10,method=bic) forward

   @dfunit(lags=10,method=bic) z

 

This uses @VARLagSelect to pick the lag length for a VAR using BIC. While the model will be an error correction model (and thus will be a restricted version of a VAR), the lag length can be chosen using the unrestricted form.

 

   @varlagselect(lags=10,crit=bic)

   # spot forward
 

This sets up the error correction equation as Z=FORWARD-SPOT.
 

   equation(coeffs=||1.0,-1.0||) ecteq z

   # forward spot

 

and this sets up the VECM (using the number of lags automatically selected):

 

   system(model=vecm)

   variables spot forward

   lags 1 to %%autop

   det constant

   ect ecteq

   end(system)

 

This estimates a straight VECM without GARCH errors, saves the log likelihood and does information criteria:

 

   estimate(model=vecm)

   compute loglmodel1=%logl

   @regcrits

 

this estimates a diagonal BEKK model without "X" regressors

 

   garch(model=vecm,mv=dbekk,pmethod=simplex,piters=10,iters=500)

   compute loglmodel2=%logl

   @regcrits

 

and this does the DBEKK model with the lagged error correction term as an "X" regressor. This uses the "separate" method for handling the X regressor in the BEKK model, though it turns out that for most of the countries the "combined" method fits quite a bit better.

 

   garch(model=vecm,mv=dbekk,xbekk=separate,pmethod=simplex,piters=10,iters=500,xreg)

   # z{1}

   compute loglmodel3=%logl

   @regcrits

 

This does likelihood ratio tests for adding the GARCH effects, and for adding the X effects to the GARCH:

 

   cdf(title="GARCH vs No GARCH") chisqr 2*(loglmodel2-loglmodel1) 4

   cdf(title="GARCH-X vs GARCH") chisqr 2*(loglmodel3-loglmodel2) 3


 


Copyright © 2025 Thomas A. Doan