# VARs

- Estimate and forecast VAR (varfcst.prg)
- VAR lag order selection (varlag.prg)
- VAR residual diagnostics (restest.prg)
- Bootstrap forecast bounds (bootfcst1.prg, bootfcst2.prg)

- Impulse response plots I (accumulated and long-run responses) (imprsp.prg)
- Impulse response plots II (asymptotic and monte carlo standard errors) (irfplot1.prg)
- Variance decomposition Monte Carlo standard errors (vdcmp.prg)

- Cholesky factorization as structural factorization (cholsvar.prg)
- Blanchard-Quah (1989) long-run restriction (blanquah1.prg)
- Short-run restriction impulse responses (Sims 1986) (sims1.prg)
- Long-run restriction impulse responses (Blanchard-Quah 1989) (blanquah2.prg)
- Bootstrap impulse response confidence bounds (bqboot.prg)

- Danish model (Johansen 1995) (johan1.prg)
- Testing cointegrating restrictions (Johansen 1995) (johan2.prg)

## Estimate and forecast VAR

The following program estimates an unrestricted VAR, creates a model object out the estimated VAR, and obtains dynamic forecasts from the VAR by solving the model object.

    ' estimate VAR and forecast
    ' replicates example in Lutkepohl (1991) pp.70-73, pp.89-91
    ' 1/7/2000 h
    ' last checked 10/27/2000 h

    'change path to program path
    %path = @runpath
    cd "{%path}"

    ' load workfile
    load lut1

    ' estimate VAR
    smpl 1960:1 1978:4
    var1.ls 1 2 y1 y2 y3 @ c

    ' replicates p.72, (3.2.22) & (3.2.24)
    ' note that the variables are ordered differently
    freeze(out1) var1.output
    show out1

    ' make model out of estimated VAR
    var1.makemodel(mod1)

    ' change sample to forecast period
    smpl 1979:1 1980:1
    ' solve model to obtain dynamic forecasts
    mod1.solve

    ' plot actual and forecasts
    smpl 1975:1 1980:1
    for !i=1 to var1.@neqn
    	group gtmp y{!i} y{!i}_0
    	freeze(gra{!i}) gtmp.line
    	%gname = %gname + "gra" + @str(!i) + " "
    next

    ' merge all graphs into one
    freeze(gfcst) {%gname}
    gfcst.align(1, 0.1, 0.5)
    gfcst.legend position(0.1,0.1)
    gfcst.scale(left) +zeroline
    show gfcst

## VAR lag order selection

This program computes various criteria to select the lag order of a VAR. The results from EViews do not quite match those reported in Lutkepohl (1991, Tables 4.4 and 4.5). While Table 4.4 reports the standard LR statistics, EViews reports the modified statistics as explained in the User's Guide, page ??. The program computes the unmodified LR statistics that exactly replicate those reported in Table 4.5 by using the log likelihood values stored in the output matrix returned from the `mname=` option in the `laglen` command. Note that the stored log likelihood values do not make a degrees of freedom adjustment to the residual covariance matrix and will not match those reported in the estimation output. The information criteria reported in Table 4.5 do not appear to include the constant term in the log likelihood. However, even after correcting for the constant term, we are not able to replicate the values for AIC, HQ, and SC in Table 4.5. (There appears to be a typo in Table 4.5. The HQ and SC values for lag order 0 are unlikely to be the same.)

    ' VAR lag order selection
    ' replicates Lutkepohl (1991)
    ' Table 4.4 (p.127) and Table 4.5 (p.130)
    ' version 4 beta
    ' 1/10/2000 h
    ' last checked 10/27/2000 h

    'change path to program path
    %path = @runpath
    cd "{%path}"

    ' load workfile
    load lut1

    ' estimate VAR
    smpl 1960:1 1978:4
    var1.ls 1 2 y1 y2 y3 @ c

    ' lag length criteria
    freeze(tab45) var1.laglen(4,vname=vlag,mname=mlag)
    show tab45

    !pi = @acos(-1)
    !c = var1.@neqn*(1+log(2*!pi))

    ' unmodified LR test (exactly replicate Table 4.4, p.127)
    ' 1st column: (unmodified) LR statistic
    ' 2nd column: p-value

    !m = @rows(mlag)-2
    matrix(!m,2) tab44
    !df = var1.@neqn * var1.@neqn	' degrees of freedom of test
    for !r=!m to 1 step -1
    	tab44(!r,1) = 2*(mlag(!r+1,1) - mlag(!r,1))
    	tab44(!r,2) = 1 - @cchisq(tab44(!r,1),!df)
    next
    show tab44

## VAR residual diagnostics

The following program computes residual diagnostics from a VAR. For the residual correlogram (autocorrelation), EViews only provides the asymptotic standard error which only depends on the sample size.

    ' VAR residual tests
    ' replicates Lutkepohl (1991, pp.148-158)
    ' version 4 beta
    ' 1/10/2000 h
    ' last checked 9/19/2000 h

    'change path to program path
    %path = @runpath
    cd "{%path}"

    ' load workfile
    load lut1

    ' estimate VAR
    smpl 1960:1 1978:4
    var1.ls 1 2 y1 y2 y3 @ c

    ' residual correlograms (Fig 4.2, p.149)
    freeze(fig42) var1.correl(12,graph)
    show fig42

    ' portmanteau test (p.152)
    freeze(tab_p152) var1.qstats(12,name=qstat)
    show tab_p152

    ' normality test (p.158)
    freeze(tab_p158) var1.jbera(factor=chol,name=jbera)
    show tab_p158

## Bootstrap forecast bounds

The sample programs bootfcst1.prg and bootfcst2.prg compute bootstrap forecast bounds. A VAR in log first differences is estimated and forecast bounds for log first differences (bootfcst1.prg) and levels (bootfcst2.prg) are computed. The bootstrap procedure is computationally intensive (time consuming) but accounts for both coefficient uncertainty and the nonlinear log transformation without assuming normality.

    'bootstrap VAR forecasts
    'no transformation
    '12/15/2000 h

    'load workfile
    %data = @runpath + "lut1"
    load "{%data}"

    'set sample objects
    sample smpl_est	 1960:1 1978:4	'estimation sample
    sample smpl_fcst 1979:1 1980:4	'forecast sample

    'estimate VAR
    smpl smpl_est
    var1.ls 1 2 y1 y2 y3 @ c

    'get residuals to bootstrap
    var1.makeresid(n=gres) res1 res2 res3

    'make model out of estimated VAR
    var1.makemodel(mod1)

    'solve model to obtain dynamic forecasts
    smpl smpl_fcst
    mod1.solve
    'rename forecasts
    smpl smpl_est
    for !i=1 to var1.@neqn
    	rename y{!i}_0 y{!i}f
    	y{!i}f = na
    next

    'assign add factors for bootstrap residuals
    mod1.addassign(i) @all

    'set monte carlo parameters
    !reps = 500						'bootstrap replications
    !hrz = smpl_fcst.@obs			'forecast horizon

    'allocate storage matrix for entire forecast distribution
    for !i=1 to var1.@neqn
    	matrix(!hrz,!reps) mboot{!i}
    next
    vector vtmp						'temporary working vector

    'set random number generator
    rndseed(type=mt) 1234567

    'bootstrap loop
    for !i=1 to !reps
    	'bootstrap residuals
    	smpl @all if res1<>na
    	gres.resample y1_a y2_a y3_a
    	'generate bootstrap data
    	mod1.solve
    	'estimate VAR with bootstrap data
    	smpl smpl_est
    	var var2.ls 1 2 y1_0 y2_0 y3_0 @ c
    	'make model from bootstrap estimates
    	var2.makemodel(mod2)
    	'solve to bootstrap forecasts
    	smpl smpl_fcst
    	mod2.solve
    	'store bootstrap forecasts
    	for !j=1 to var2.@neqn
    		stom(y{!j}_0_0, vtmp, smpl_fcst)
    		colplace(mboot{!j}, vtmp, !i)
    	next
    	'clean up
    	delete mod2
    next

    'find bootstrap percentiles for each horizon
    matrix(!hrz,var1.@neqn) mupp	'upper percentile
    matrix(!hrz,var1.@neqn) mlow	'lower percentile
    rowvector rtmp					'temporary working vector

    for !i=1 to !hrz
    	for !j=1 to var1.@neqn
    		rtmp = @rowextract(mboot{!j},!i)
    		mupp(!i,!j) = @quantile(rtmp,0.975)
    		mlow(!i,!j) = @quantile(rtmp,0.025)
    	next
    next

    'plot actual and forecasts
    smpl 1975:1 1980:4
    for !i=1 to var1.@neqn
    	'convert bounds into series
    	series y{!i}_upp
    	vtmp = @columnextract(mupp,!i)
    	mtos(vtmp, y{!i}_upp, smpl_fcst)

    	series y{!i}_low
    	vtmp = @columnextract(mlow,!i)
    	mtos(vtmp, y{!i}_low, smpl_fcst)
    	'plot graph
    	group gtmp y{!i} y{!i}f y{!i}_upp y{!i}_low
    	freeze(gra{!i}) gtmp.line
    	gra{!i}.setelem(1) legend(actual)
    	gra{!i}.setelem(2) legend(forecast)
    	gra{!i}.setelem(3) legend(bootstrap bounds)
    	gra{!i}.setelem(4) legend()

    	%gname = %gname + "gra" + @str(!i) + " "
    next

    ' merge all graphs into one
    freeze(gfcst) {%gname}
    gfcst.options size(8,2)
    gfcst.align(1, 0.1, 0.5)
    gfcst.legend columns(1) -inbox position(0.1,0.1)
    'gfcst.scale(left) +zeroline
    gfcst.option linepat	' need to set linepat
    gfcst.draw( dashline,left,rgb(155,155,155) ) 0.0
    gfcst.elem(1) lcolor(blue) lpat(solid)
    gfcst.elem(2) lcolor(red) lpat(solid)
    gfcst.elem(3) lcolor(red) lpat(dash1)
    gfcst.elem(4) lcolor(red) lpat(dash1)
    gfcst.addtext(0.1,-0.2) Bootstrap Forecast Bounds

    show gfcst