*
* @ROLLREG( options )  depvar  first  last
* # list of regressors
*
* This procedure does rolling OLS regressions in one of three modes.
* Given an initial range of observations, ADD adds observations (one at
* a time) to the end of the sample, DROP drops them from the beginning
* of the sample, and MOVE simultaneously adds and drops so that the
* number of observations in each regression is constant.
*
* Parameters:
*   depvar            is the name of the LHS variable
*   first last        (optional) maximum range for the regression
*                     defaults to maximum range for which all variables
*                     are defined
* Supplementary card:
*   list of series    lists the RHS variables for the regression
*
* Options:
* ADD=              starting with a regression from  first  to  ADD,
*                   adds one observations at a time until it does a
*                   regression from  first  to  last
* DROP=             starting with a regression from  first  to  last,
*                   drops one observations at a time until it does a
*                   regression from  DROP  to  last
* MOVE=             starting with a regression from first to first+MOVE-1
*                   adds and drops one observations at a time until it
*                   does a regression from  last-move+1  to  last
*                   (i.e. there are MOVE observations in each regression)
*
* Note that exactly one of these three options must be used.
*
* e.g. @rollreg(drop=1989:4) gnp
*      @rollreg(add=1971:4) gnp
*      @rollreg(move=20) gnp
*
* ROBUST/[NOROBUST] uses the ROBUSTERRORS option to calculate the
*                   standard errors.
* LAGS = [0]        number of lags to use with the ROBUST option.
*                   This does **not** vary with the degrees of freedom.
* LWINDOW=[NEWEY]/BARTLETT/DAMPED/PARZEN/QUADRATIC
*                   chooses lag window type. Note that the default for
*                   ROLLREG is the Newey-West, rather than the truncated
*                   window.
* DAMP = [1.0]      shape of the spectral window to use with the
*                   LWINDOW=DAMPED option.
*
* Output Options:
*
* COHISTORY  = VECT[SERIES] for the coefficients
* SEHISTORY  = VECT[SERIES] for the standard errors of the coefficients
* SIGHISTORY = SERIES for the regression standard errors
* (These are all similar to the options for the RLS instruction)
*
* FHISTORY   = SERIES with regression F's
*
* PRINT]/[NOPRINT]  prints the coefficient estimates
* WINDOW  =         title for print window
* GRAPH/[NOGRAPH]   graphs the coefficients with two standard error bands.
*
* Revision Schedule:
*   October 1992 Written by Simon van Norden
*   August 1993  Modified for RATS v4 by Jeff Gable
*   June 1995    Robust Error Bug Fix by Rob Vigfusson
*   March 2009   Minor change to description by Tom Doan, Estima
*   June 2010    Major reprogramming by Tom Doan, Estima to use newer
*                features and make more compatible with syntax of the
*                RLS instruction.
*   April 2011   Add FHISTORY option. Tom Doan, Estima.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*  ROLLREG.SRC
*  Copyright 1993 by the Bank of Canada
*  Programmed for RATS by Robert Amano, Jeff Gable and Simon van Norden
*  In exchange for access to these procedures, users are requested to
*  acknowledge the use of the Bank of Canada RATS procedures in
*  all published work.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
procedure rollreg  y  first last
type series             y
type integer            first last
option integer 			add      0
option integer 			drop     0
option integer 			move     0
option switch  			robust   0
option choice			   lwindow	3	newey bartlett damped parzen quadratic flat
option integer 			lags     0
option real    			damp     1.0
option switch  			print    0
option string           window
option switch  			graph    0
option vect[series] 		*cohistory
option vect[series] 		*sehistory
option series       		*sighistory
option series           *fhistory
*
local integer           fobs lobs cut k fbeta lbeta
local equation          eqn
local vect[series]      coeff
local vect[series]      se
local series            upper lower
*
* Define the system to be estimated and initialize
*
* 06/2010 Switch to use EQUATION
*
equation eqn y
*
* 06/2010 Move diagnostic here
*
if (add<>0)+(drop<>0)+(move<>0) != 1 {
   disp "###ROLLREG: Must use one and only one of ADD, DROP and MOVE options."
   return
}
*
* Get default range
*
inquire(equation=eqn) fobs<<first lobs<<last
*
* Figure out the range over which we will have coefficient estimates
*
if add
   compute fbeta=add,lbeta=lobs
else
if drop
   compute fbeta=fobs,lbeta=drop
else
   compute fbeta=fobs+move-1,lbeta=lobs

compute %nreg=%eqnsize(eqn)
dim coeff(%nreg) se(%nreg)
if %defined(cohistory) ; dim cohistory(%nreg)
if %defined(sehistory) ; dim sehistory(%nreg)
do k=1,%nreg
   if %defined(cohistory)
      set cohistory(k) fbeta lbeta = 0.0
   set coeff(k) fbeta lbeta = 0.0
   if %defined(sehistory)
      set sehistory(k) fbeta lbeta = 0.0
   set se(k)     fbeta lbeta = 0.0
end do i
if %defined(sighistory)
   set sighistory fbeta lbeta = 0.0
if %defined(fhistory)
   set fhistory fbeta lbeta = 0.0

if add
   {
   *
   * Adding observations to end
   *
   do cut=fbeta,lbeta
      if robust
         linreg(equation=eqn,noprint,$
           robusterrors,lwindow=lwindow,lags=lags,damp=damp) y fobs cut
      else
         linreg(equation=eqn,noprint) y fobs cut
      if %defined(cohistory)  ; compute %pt(cohistory,cut,%beta)
      if %defined(sehistory)  ; compute %pt(sehistory,cut,%stderrs)
      if %defined(sighistory) ; compute sighistory(cut)=sqrt(%seesq)
      if %defined(fhistory)   ; compute fhistory(cut)=%fstat
      compute %pt(coeff,cut,%beta),%pt(se,cut,%stderrs)
   end do cut
   }
else if drop
   {
   *
   * Dropping observations from start
   *
   compute fbeta=fobs,lbeta=drop
   do cut=fbeta,lbeta
      if robust
         linreg(equation=eqn,noprint,$
            robusterrors,lwindow=lwindow,lags=lags,damp=damp) y cut lobs
      else
         linreg(equation=eqn,noprint) y cut lobs
      if %defined(cohistory)  ; compute %pt(cohistory,cut,%beta)
      if %defined(sehistory)  ; compute %pt(sehistory,cut,%stderrs)
      if %defined(sighistory) ; compute sighistory(cut)=sqrt(%seesq)
      if %defined(fhistory)   ; compute fhistory(cut)=%fstat
      compute %pt(coeff,cut,%beta),%pt(se,cut,%stderrs)
   end do cut
   }
else if move
   {
   *
   * Moving sample regression
   *
   compute fbeta=fobs+move-1,lbeta=lobs
   do cut=fbeta,lbeta
      if robust
         linreg(equation=eqn,noprint,$
            robusterrors,lwindow=lwindow,lags=lags,damp=damp) y cut-move+1 cut
      else
         linreg(equation=eqn,noprint) y cut-move+1 cut
      if %defined(cohistory)  ; compute %pt(cohistory,cut,%beta)
      if %defined(sehistory)  ; compute %pt(sehistory,cut,%stderrs)
      if %defined(sighistory) ; compute sighistory(cut)=sqrt(%seesq)
      if %defined(fhistory)   ; compute fhistory(cut)=%fstat
      compute %pt(coeff,cut,%beta),%pt(se,cut,%stderrs)
   end do cut
   }
*
* Now output the results
*
if graph {
   do k=1,%nreg
      set lower fbeta lbeta = coeff(k)-se(k)*1.96
      set upper fbeta lbeta = coeff(k)+se(k)*1.96
      graph(hlabel=%eqnreglabels(eqn)(k)) 3
      # coeff(k) fbeta lbeta
      # lower    fbeta lbeta 2
      # upper    fbeta lbeta 2
   end do k
}
if print {
   labels coeff
   # %eqnreglabels(eqn)
   print(window=window) fbeta lbeta coeff
}
*
end proc rollreg


