RATS 11.1
RATS 11.1

The first widespread use of simulation techniques in econometrics was Monte Carlo integration for VAR’s and it probably remains the most common introduction to simulation methods for people.

 

The impulse responses from a VAR are highly non-linear functions of the coefficients. Monte Carlo integration is one way to examine the distribution of these, so we can properly access the statistical significance of the point values that are generated by IMPULSE. Other calculations routinely done with VAR’s, such as forecasts, also are simple only if the coefficients are assumed to be known. Like IRF’s, allowing for uncertainty in the lag coefficients creates a non-linear function which cannot easily be analyzed except by simulation methods. One very nice property of Monte Carlo methods is that the same basic method for simulating the VAR can be applied to any subsequent calculation, whether it’s for impulse responses, error decompositions or forecasting.

 

What we will discuss in this section is the application of the techniques of “Multivariate Normal Regression (VAR)—Jeffreys Prior” to a (full) VAR with a diffuse (Jeffrey’s) prior. A VAR with a prior, a near-VAR, or an overidentified structural VAR are more difficult because the posterior doesn’t “factor”—those require some combination of the other techniques such as Importance Sampling, Gibbs Sampling and Metropolis-Hastings. Those are more complicated to set up and require more care to ensure that you get good results. By contrast, the method here is straightforward and has very good Monte Carlo properties.

 

As is the case with many applications of simulation techniques, there is actually more programming involved in extracting the information from the simulations than in doing the simulations themselves. Because the desired organization of the impulse response graphs is generally the same regardless of the method used to generate the draws, we’ve written a special procedure @MCGraphIRF to do the graphs.

 

The output from a full Monte Carlo run on a VAR is a complicated set of multi-dimensional data. Each draw has NSTEPS responses, each of which has NSHOCKS shocks and NVAR target variables. To make possible the use of a set of standard procedures for post-processing the draws, these need to be packed in a certain way: into a VECT[RECT] called %%RESPONSES. How this is structured is described in "%%RESPONSES".

 

Generating Draws: MONTEVAR.RPF example

Under the convenient assumptions for the full VAR with the Jeffrey’s prior, the \(\Sigma\) matrix can be drawn unconditionally, then the lag coefficients can be drawn conditional on \(\Sigma\).

 

This is extremely quick since the factor of the biggest matrix \(({\bf{X'X}})^{ - 1} \) can be computed just once, outside the loop. In MONTEVAR.RPF, after the VAR has been set up and estimated, the following computes factors of two key matrices into FXX and FWISH, saves the OLS estimates into BETAOLS and saves two other useful pieces of information.

 

estimate

 

compute nvar    = %nvar

compute fxx     = %decomp(%xx)

compute fwish   = %decomp(inv(%nobs*%sigma))

compute wishdof = %nobs-%nreg

compute betaols = %modelgetcoeffs(varmodel)

 

Inside the loop, this uses antithetic acceleration by drawing a new value of \(\Sigma\) and \(\bf{\beta}\) on the odd draws, then flipping the sign of the deviation between the draw and the OLS estimates (the mean of the posterior) on the even draws. SIGMAD is a draw for the covariance matrix (which requires only the sample values of FWISH and WISHDOF, since it has an unconditional distribution), FSIGMA is the factor of it and BETAU is the randomly drawn Normal addition to the OLS estimates to get the (odd-valued) draw. On the even numbered draws, the previous value for \(\Sigma\) is retained, and the antithetic value for the coefficients is generated by subtracting BETAU rather than adding. 

 

  if %clock(draw,2)==1 {

      compute sigmad  =%ranwisharti(fwish,wishdof)

      compute fsigma  =%decomp(sigmad)

      compute betau   =%ranmvkron(fsigma,fxx)

      compute betadraw=betaols+betau

   }

   else

      compute betadraw=betaols-betau

 

The following resets the coefficient matrix for the working VAR:

 

compute %modelsetcoeffs(varmodel,betadraw) 

 

and this computes and saves the impulse responses using the Cholesky factor shocks:

 

  impulse(noprint,model=varmodel,factor=fsigma,$

   results=impulses,steps=nstep,flatten=%%responses(draw))

 

This can be adapted to (almost) any just–identified structural VAR by replacing the FACTOR option on the IMPULSE with some other factorization of SIGMAD. However, it will almost always be easier to use the @MONTEVAR or @MCVARDoDraws procedures with an FFUNCTION option to do that. Where the program here is helpful is when you need to generate draws from this type of model for other reasons (such as analyzing out-of-sample forecasts).

 

Note that the use of antithetic acceleration isn't needed to make this work. In practice, it seems to improve the efficiency of the integral by a factor of 3 or 4, but that's unlikely to be an issue with a simulation routine as simple as this. Without it, you would need only

 

      compute sigmad  =%ranwisharti(fwish,wishdof)

      compute fsigma  =%decomp(sigmad)

      compute betau   =%ranmvkron(fsigma,fxx)

      compute betadraw=betaols+betau

 

without the IF and ELSE.

@MCGRAPHIRF Procedure

@MCGraphIRF has quite a few options. The default behavior, which we use here, will generate an \(n \times n\) “matrix” of graphs, with the responses of a variable in a row, the response to a variable in a column. Following the recommendation of Sims and Zha (1999), this displays percentile bands, not standard errors. The 16% and 84% quantiles correspond to one standard deviation if we were doing symmetrical error bands based upon estimates of the variance. If you want standard error bands instead, you can use the STDDEV option. In our case, we do:

 

@mcgraphirf(model=varmodel)

 

Other useful options are SHOCKLABELS and VARLABELS, which let you relabel the shocks and endogenous variables to something more informative. (By default, both use the labels of the endogenous variables).

 

@MCPROCESSIRF Procedure

If the options of @MCGRAPHIRF can’t create the type of graph you want (or if you want some non-graphical output), you can use @MCPROCESSIRF to get the same information, such as RECT[SERIES] with the upper and lower bounds, but not the graphs. Like @MCGRAPHIRF, this also requires that the responses be packed into the %%RESPONSES matrix.

 

@MCFEVDTABLE Procedure 

@MCFEVDTABLE uses the %%RESPONSES information to produce a table with error bands for the decomposition of variance. Note that this assumes that the shocks used in generating %%RESPONSES are orthogonalized and produce a complete factorization of the covariance matrix. It cannot be used with isolated or non-orthogonalized shocks. Also note that the results can seem quite odd,  particularly with a larger model—it’s not uncommon for the point estimates to be outside the error bands due to how highly asymmetric the variance decomposition can be. It is not, and should not be, considered standard practice to include this.

 

@MONTEVAR and @MCVARDoDraws procedures

In practice, you wouldn’t adapt the MONTEVAR.RPF program to do the IRF error bands with a different data set—the @MONTEVAR procedure can be applied immediately after the ESTIMATE instruction to do the remainder of the calculations. In this case, it would be done with

 

@montevar(model=varmodel,step=nstep,draws=ndraws)

 

@MONTEVAR also has a FFUNCTION option which allows you to input a function to do an alternative factorization and a FACTOR option to input a specific (fixed) alternative set of shocks. The FFUNCTION is a FUNCTION which takes the draw for the covariance matrix and the draw for the MODEL as parameters—the latter is if you need to adjust based upon the coefficients themselves (for instance, if you have long-run restrictions: see below).

 

If you want to do non-orthogonal shocks, you can use FFUNCTION if your shocks depend upon the draw for \(\Sigma\) or FACTOR if it doesn't. For instance, with FACTOR=%UNITV(NVAR,1), you’ll get just unit shocks to the first variable (so NSHOCKS will be 1).

 

If you want to control the graphics, instead of using @MONTEVAR, you can use @MCVARDoDraws which generates the %%RESPONSES array for use with @MCGraphIRF or @MCProcessIRF. Like @MONTEVAR, this has FFUNCTION and FACTOR options. These all use the same methods shown in this section.

 

Models with Long-Run Restrictions

Note that if you do any calculation with long-run restrictions, you need to recompute the sum of lag coefficients with the %MODELLAGSUMS function—%VARLAGSUMS is calculated at the OLS estimates only and doesn’t reflect the fact that you have just drawn a new set. The %BQDODRAWS procedure is a Monte Carlo draw procedure (to replace @MCVARDoDraws) which handles the specific case of the Blanchard-Quah two variable model.

 

Overidentified Structural VAR's

The calculations done by the MONTEVAR.RPF program or by these procedures can’t be used for an overidentified structural VAR—that requires the use of importance sampling or Metropolis-Hastings. (The draw for \(\Sigma\) can't be done unconditionally as it can with a just-identified model). And even for some just-identified factorizations which can’t be done with simple matrix operations (if you need, for instance, CVMODEL to calculate the parameters), you may better off also using one of those techniques rather than estimating the SVAR every draw with CVMODEL.

 


Copyright © 2026 Thomas A. Doan