Gibbs Var with Minnesota Prior and Exogenous Variables

Questions and discussions on Vector Autoregressions
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Dear Tom,

I wrote some code for a Gibbs sampler for a VAR with Minnesota Prior and exogenous variables.
I used the haversample data.
Could you have a look at the code and tell me whether it is fine?

Code: Select all


************************
********* Data *********
************************

open data haversample.rat
cal(q) 1959
data(format=rats) 1959:1 2006:4 ftb3 gdph ih cbhm

set loggdp = log(gdph)
set loginv = log(ih)
set logc   = log(cbhm)




***************************************
************ General Setup ************
***************************************


compute lags=4                                 ;*Number of lags
compute nstep=50                               ;*Number of response steps
compute ndraws=1000                            ;*Number of keeper draws
compute nburn=500                              ;*Number of burn-in draws
compute keep = ndraws - nburn                  ;*Number of kept draws
compute nvari = 3                              ;*Number of endogebous variables
compute nexog = 1                              ;*Number of exogenous variables
compute ncoef = nvari*lags+nexog*lags+1        ;*Number of coefficients per equation, +1 for intercept +12 for each exogenous variable


***********************************
************ VAR Setup ************
***********************************

*set time = t


compute tight= 0.2
compute other= 0.5

system(model=var)
   variables loggdp loginv logc
   lags 1 to lags
   det constant ftb3{1 to lags} 
end(system)



estimate(noprint,ols,sigma)                                       ;*for initial draw of VAR coefficients
impulse(noprint,model=var,steps=nstep,results=impulses)          ;*initial set of of impulse responses


compute start = %REGSTART()                                       ;* Starting Period for Structural Residual Estimation
compute end = %REGEND()                                           ;* Ending Period for Structural Residual Estimation
compute nvar=%nvar                                                ;* Number of equations estimated


declare vect olssee(nvar)                                         ;* vector of variances, with standard errors estimated from univariat AR(1) models
compute i = 1
dofor x = loggdp loginv logc

   linreg(noprint) x
   # constant x{1}

   compute olssee(i) = sqrt(%SEESQ)
   compute i = i+1

end do



declare vect[rect] %%responses(keep)                              ;* Storage Vector of Rectanculars for Impulse Response Draws                                   ;* Storage Series of vectors for Kilian IRF Projection
declare series[rect] bgibbs                                       ;* Storage Series of Rectangulars to save the VAR Coefficient Draws

gset bgibbs 1 keep = %zeros(ncoef,nvari)                          ;* To dimension the storage matrix inside the series



***********************************
********* Minnesota Prior *********
***********************************



* Create the prior mean and (square root of) precision. The olssee
* values are used to scale the precision. The prior mean is 1 for the
* first own lag in each equation, and 0 otherwise. The constant is given
* a mean of zero with a standard deviation according to Meinen and Roehe: lambda4*olssee(i), lambda4=100

dec rect minnmean(ncoef,nvar) minnprec(ncoef,nvar)

do i=1,nvar
   do j=1,nvar
      do l=1,lags
         compute minnmean((j-1)*lags+l,i)=%if(i==j.and.l==1,1,0)                                   ;* sets first on log to 1 and everything else to zero
         compute minnprec((j-1)*lags+l,i)=(olssee(j)/olssee(i))*%if(i==j,l/tight,l/(other*tight))  ;* computes the corresponding minnesota precisions
      end do l
   end do j

   do k = 0,nexog*lags
      compute minnmean(ncoef-k,i)=0.0,minnprec(ncoef-k,i)=100*olssee(i)                                   ;* sets the minnesota mean and precision for the exogenous regressors
   end do k

end do i



ewise minnprec(i,j)=minnprec(i,j)^2
compute hprior=%diag(%vec(minnprec))
compute bprior=minnmean


compute sigmad=%sigma
cmom(model=var)                                                                               ;* Cmom computes the cross moment matrix %cmom, which is the X'X matrix. It is deterministic and data dependent.


*********************************
********* Gibbs Sampler *********
*********************************



infobox(action=define,progress,lower=1,upper=ndraws) "Gibbs Sampler"
do draw= 1,ndraws
   infobox(current=draw)
   *
   * Draw b given sigma
   *
   compute bdraw =%ranmvkroncmom(%cmom,inv(sigmad),hprior,bprior)
   compute rssmat=%sigmacmom(%cmom,bdraw)
   *
   * Draw sigma given b
   *
   compute sigmad=%ranwisharti(%decomp(inv(rssmat)),%nobs)
   if draw<=nburn
      next

   compute %modelsetcoeffs(var,bdraw)
   impulse(noprint,model=var,results=impulses,steps=nstep,flatten=%%responses(draw-nburn))

   * Bookkeeping:

   compute bgibbs(draw-nburn) = bdraw    ;* Saves the Draws of the VAR Coefficients

end do draw
infobox(action=remove)



***********************
********* IRF *********
***********************

@mcgraphirf(model=var,center=median,percent=||0.16,0.84||)

PS: The exogenous variable is chosen arbitrarily. So it does not neccesarily make economic sense to model it like this... It is just to play around with the code

Best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

If your "exogenous" variable is a set of lags of another variable, then it should be handled the same way that the lagged dependents are handled. You're using the prior that's reasonable for the constant, where the scale depends only upon the scale of the dependent variable; not for an observed variable where the coefficients will be dependent upon both the scale of the dependent variable and on the scale of the exogenous variable.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Dear Tom,

the part in the minnesota prior which handels the exogenous variables is based on Koop and Korobilis http://personal.strath.ac.uk/gary.koop/kk3.pdf page 7.
They put (sigma_i * hyperparameter) for exogenous variables. Is this not a good idea?

Best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

I'm not sure what you're talking about. The only exogenous variable is the CONSTANT, and they say:

"Exogenous variables or more deterministic terms (e.g. deterministic trends or
seasonals) can easily be added to the VAR and included in all the derivations
below, but we do not do so to keep the notation as simple as possible"
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

You are right... I got that wrong. So I adjust the "exogenous" variables, which are lags of a variable in the following way:

1. I calculate their standard deviation from an AR(1) model: olssee(k)
2. I adjust in the following way: (olssee(k)/olssee(i))*l/(other*tight), for equation i and lag l

Right?

Thank you very much

Best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

Correct.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Dear Tom,

according to your suggestion I have adjusted the code:

Code: Select all


************************
********* Data *********
************************

open data haversample.rat
cal(q) 1959
data(format=rats) 1959:1 2006:4 ftb3 gdph ih cbhm

set loggdp = log(gdph)
set loginv = log(ih)
set logc   = log(cbhm)




***************************************
************ General Setup ************
***************************************


compute lags=4                                 ;*Number of lags
compute nstep=50                               ;*Number of response steps
compute ndraws=1000                            ;*Number of keeper draws
compute nburn=500                              ;*Number of burn-in draws
compute keep = ndraws - nburn                  ;*Number of kept draws
compute nvari = 3                              ;*Number of endogebous variables
compute nexog = 1                              ;*Number of exogenous variables
compute ncoef = nvari*lags+nexog*lags+1        ;*Number of coefficients per equation, +1 for intercept +12 for each exogenous variable


***********************************
************ VAR Setup ************
***********************************

*set time = t


compute tight= 0.2
compute other= 0.5

system(model=var)
   variables loggdp loginv logc
   lags 1 to lags
   det constant ftb3{1 to lags}
end(system)



estimate(noprint,ols,sigma)                                       ;*for initial draw of VAR coefficients
impulse(noprint,model=var,steps=nstep,results=impulses)          ;*initial set of of impulse responses


compute start = %REGSTART()                                       ;* Starting Period for Structural Residual Estimation
compute end = %REGEND()                                           ;* Ending Period for Structural Residual Estimation
compute nvar=%nvar                                                ;* Number of equations estimated


declare vect olssee(nvar)                                         ;* vector of variances, with standard errors estimated from univariat AR(1) models
declare vect olsseex(nexog)                                       ;* vector of standard deviations for "exogenous" variables constructed from univariat AR(1) models
compute i = 1
compute j = 1

dofor x = loggdp loginv logc

   linreg(noprint) x
   # constant x{1}

   compute olssee(i) = sqrt(%SEESQ)
   compute i = i+1

end do

dofor x = ftb3

   linreg(noprint) x
   # constant x{1}

   compute olsseex(j) = sqrt(%SEESQ)
   compute j = j+1

end do 

declare vect[rect] %%responses(keep)                              ;* Storage Vector of Rectanculars for Impulse Response Draws                                   ;* Storage Series of vectors for Kilian IRF Projection
declare series[rect] bgibbs                                       ;* Storage Series of Rectangulars to save the VAR Coefficient Draws

gset bgibbs 1 keep = %zeros(ncoef,nvari)                          ;* To dimension the storage matrix inside the series



***********************************
********* Minnesota Prior *********
***********************************



* Create the prior mean and (square root of) precision. The olssee
* values are used to scale the precision. The prior mean is 1 for the
* first own lag in each equation, and 0 otherwise. The constant is given
* a mean of zero with a standard deviation according to Meinen and Roehe: lambda4*olssee(i), lambda4=100

dec rect minnmean(ncoef,nvar) minnprec(ncoef,nvar)

do i=1,nvar
   do j=1,nvar
      do l=1,lags
         compute minnmean((j-1)*lags+l,i)=%if(i==j.and.l==1,1,0)                                            ;* sets first on log to 1 and everything else to zero
         compute minnprec((j-1)*lags+l,i)=(olssee(j)/olssee(i))*%if(i==j,l/tight,l/(other*tight))           ;* computes the corresponding minnesota precisions
      end do l
   end do j
   
   do m = 1,nexog
      do k = 1,nexog*lags
         compute minnmean(ncoef-k,i)=0.0,minnprec(ncoef-k,i)= (olsseex(m)/olssee(i))*(l/(other*tight))      ;* sets the minnesota mean and precision for the "exogenous" parameters (this includes adjustment in the precision)
      end do k
   end do

   compute minnmean(ncoef,i)=0.0,minnprec(ncoef,i)=100*olssee(i)                                            ;* sets the mean and precision for the intercept

end do i



ewise minnprec(i,j)=minnprec(i,j)^2
compute hprior=%diag(%vec(minnprec))
compute bprior=minnmean


compute sigmad=%sigma
cmom(model=var)                                                                               ;* Cmom computes the cross moment matrix %cmom, which is the X'X matrix. It is deterministic and data dependent.


*********************************
********* Gibbs Sampler *********
*********************************



infobox(action=define,progress,lower=1,upper=ndraws) "Gibbs Sampler"
do draw= 1,ndraws
   infobox(current=draw)
   *
   * Draw b given sigma
   *
   compute bdraw =%ranmvkroncmom(%cmom,inv(sigmad),hprior,bprior)
   compute rssmat=%sigmacmom(%cmom,bdraw)
   *
   * Draw sigma given b
   *
   compute sigmad=%ranwisharti(%decomp(inv(rssmat)),%nobs)
   if draw<=nburn
      next

   compute %modelsetcoeffs(var,bdraw)
   impulse(noprint,model=var,results=impulses,steps=nstep,flatten=%%responses(draw-nburn))

   * Bookkeeping:

   compute bgibbs(draw-nburn) = bdraw    ;* Saves the Draws of the VAR Coefficients

end do draw
infobox(action=remove)



***********************
********* IRF *********
***********************

@mcgraphirf(model=var,center=median,percent=||0.16,0.84||)

It would be very kind if you again could have a look at it and tell me whether everything is correct.

Thank you in advance

Best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

Offhand, it doesn't look like the precision for the exogenous variables is going into the right slots. You could simplify the whole thing considerably by just adding the exogenous variables onto the end of the olssee calculations (rather than doing them all separately) and running the loop to set up the priors over:
do i=1,nvar
   do j=1,nvar+nexog
...
After all, the only difference in treatment between the exogenous variable(s) and the endogenous ones is whether there's an equation for the variable.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Thanks! Here is a corrected version. I hote this fits well

Code: Select all


************************
********* Data *********
************************

open data haversample.rat
cal(q) 1959
data(format=rats) 1959:1 2006:4 ftb3 gdph ih cbhm

set loggdp = log(gdph)
set loginv = log(ih)
set logc   = log(cbhm)




***************************************
************ General Setup ************
***************************************


compute lags=4                                 ;*Number of lags
compute nstep=50                               ;*Number of response steps
compute ndraws=1000                            ;*Number of keeper draws
compute nburn=500                              ;*Number of burn-in draws
compute keep = ndraws - nburn                  ;*Number of kept draws
compute nvari = 3                              ;*Number of endogebous variables
compute nexog = 1                              ;*Number of exogenous variables
compute ncoef = nvari*lags+nexog*lags+1        ;*Number of coefficients per equation, +1 for intercept +12 for each exogenous variable


***********************************
************ VAR Setup ************
***********************************

*set time = t


compute tight= 0.2
compute other= 0.5

system(model=var)
   variables loggdp loginv logc
   lags 1 to lags
   det constant ftb3{1 to lags}
end(system)



estimate(noprint,ols,sigma)                                       ;*for initial draw of VAR coefficients
impulse(noprint,model=var,steps=nstep,results=impulses)          ;*initial set of of impulse responses


compute start = %REGSTART()                                       ;* Starting Period for Structural Residual Estimation
compute end = %REGEND()                                           ;* Ending Period for Structural Residual Estimation
compute nvar=%nvar                                                ;* Number of equations estimated


declare vect olssee(nvar+nexog)                                         ;* vector of variances, with standard errors estimated from univariat AR(1) models
compute i = 1

dofor x = loggdp loginv logc ftb3

   linreg(noprint) x
   # constant x{1}

   compute olssee(i) = sqrt(%SEESQ)
   compute i = i+1

end do


declare vect[rect] %%responses(keep)                              ;* Storage Vector of Rectanculars for Impulse Response Draws                                
declare series[rect] bgibbs                                       ;* Storage Series of Rectangulars to save the VAR Coefficient Draws

gset bgibbs 1 keep = %zeros(ncoef,nvari)                          ;* To dimension the storage matrix inside the series



***********************************
********* Minnesota Prior *********
***********************************



* Create the prior mean and (square root of) precision. The olssee
* values are used to scale the precision. The prior mean is 1 for the
* first own lag in each equation, and 0 otherwise. The constant is given
* a mean of zero with a standard deviation according to Meinen and Roehe: lambda4*olssee(i), lambda4=100

dec rect minnmean(ncoef,nvar) minnprec(ncoef,nvar)

do i=1,nvar
   do j=1,nvar+nexog
      do l=1,lags
         compute minnmean((j-1)*lags+l,i)=%if(i==j.and.l==1,1,0)                                            ;* sets first on log to 1 and everything else to zero
         compute minnprec((j-1)*lags+l,i)=(olssee(j)/olssee(i))*%if(i==j,l/tight,l/(other*tight))           ;* computes the corresponding minnesota precisions
      end do l
   end do j

   compute minnmean(ncoef,i)=0.0,minnprec(ncoef,i)=100*olssee(i)                                            ;* sets the mean and precision for the intercept

end do i



ewise minnprec(i,j)=minnprec(i,j)^2
compute hprior=%diag(%vec(minnprec))
compute bprior=minnmean


compute sigmad=%sigma
cmom(model=var)                                                                               ;* Cmom computes the cross moment matrix %cmom, which is the X'X matrix. It is deterministic and data dependent.


*********************************
********* Gibbs Sampler *********
*********************************



infobox(action=define,progress,lower=1,upper=ndraws) "Gibbs Sampler"
do draw= 1,ndraws
   infobox(current=draw)
   *
   * Draw b given sigma
   *
   compute bdraw =%ranmvkroncmom(%cmom,inv(sigmad),hprior,bprior)
   compute rssmat=%sigmacmom(%cmom,bdraw)
   *
   * Draw sigma given b
   *
   compute sigmad=%ranwisharti(%decomp(inv(rssmat)),%nobs)
   if draw<=nburn
      next

   compute %modelsetcoeffs(var,bdraw)
   impulse(noprint,model=var,results=impulses,steps=nstep,flatten=%%responses(draw-nburn))

   * Bookkeeping:

   compute bgibbs(draw-nburn) = bdraw    ;* Saves the Draws of the VAR Coefficients

end do draw
infobox(action=remove)



***********************
********* IRF *********
***********************

@mcgraphirf(model=var,center=median,percent=||0.16,0.84||)

Does it?

Best Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

That looks correct.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Dear Tom,

I think I spotted two mistakes in the code above I would like to correct in case anybody wants to use this code:

1) It's about the precision parameter on the intercept in the Minnesota Prior. When there are also exogenous variables, which are lags of some other variable the system has to be set up differently to use the Minnesota Prior loop.
At the moment its like this:

Code: Select all


system(model=var)
   variables loggdp loginv logc
   lags 1 to lags
   det constant ftb3{1 to lags}
end(system)

But the Minnesota loop is set up such that the constant is always the last coefficient, which is estimated. Therefore to use the Minnesota loop as it is, the system should be set up like this:

Code: Select all

system(model=var)
   variables loggdp loginv logc
   lags 1 to lags
   det  ftb3{1 to lags} constant
end(system)
Otherwise the precision of the intercept does not go into the right slot.

2) When doing IRFs on every Gibbs draw, shoudn't the Cholesky decomposition of every draw for the covariance matrix be used? Then the IMPULSE instruction should be modified like this:

Code: Select all


   **************************
   *** Draw sigma given b ***
   **************************

   compute sigmad=%ranwisharti(%decomp(inv(rssmat)),%nobs)
   compute fact = %decomp(sigmad)

   if draw<=nburn
      next

   *******************************************
   *** Set Modelcoefficients and draw IRFs ***
   *******************************************

   compute %modelsetcoeffs(varexog,bdraw)
   impulse(noprint,model=varexog,results=impulses,steps=nstep,flatten=%%responses(draw-nburn),factor=fact)
I hope that the changes are correct.

Thank you

best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

The first is correct. The second is correct if that's (Cholesky factor) what you want.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Thank you for the quick reply.
According to the second statement: yes I meant the cholesky decomposition for the IRFs. The previous code used always the same covariance matrix within the impulse instruction, namely the one of the OLS estimates previous to the Gibbs sampler. But since the Gibbs sampler samples a new covariance matrix on every draw, the drawn covariance matrix should be used within the IMPULSE instruction to orthogonbalize the residuals for the IRFs. Of course all of this is only true if you want to identify your SVAR by the recursive identification scheme, which the cholesky decomposition implies.
I think an alternative, which yields the same results would be to use CV=SIGMAD instead of FACTOR=FACT as an option in the impulse instruction, right?


Best

Jules
TomDoan
Posts: 7814
Joined: Wed Nov 01, 2006 4:36 pm

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by TomDoan »

Yes. Those would be the same.
Jules89
Posts: 140
Joined: Thu Jul 14, 2016 5:32 am

Re: Gibbs Var with Minnesota Prior and Exogenous Variables

Unread post by Jules89 »

Since the prior on the inverse Wishart distribution is uninformative, is there a way to make it informative by including a scale matrix (for example a diagonal with the AR(1) variances on the diagonal). Is it possible to include that in the %ranwisharti() fuction?

best

Jules
Post Reply