 env noecho
*
* ROLLREG.SRC            by Simon van Norden           10-11-1992
* Copyright 1993, 1992, 1990 by Bank of Canada
* (modified for RATS v4 August 1993 by Jeff Gable)
* (Robust Error Bug Fix  June 1995 by Rob Vigfusson)
*
* 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.
*
* The syntax is
* @ROLLREG  depvar  first last
* # list of series
* where
* depvar            is the name of the LHS variable
* list of series    lists the RHS variables for the regression
* first, last       (optional) maximum range for the regression
*                   defaults to maximum range for which all variables
*                   are defined
* 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.
* Also note that if you use dates with any of the above options, you must
* enclose the dates in parentheses.
* e.g. @rollreg(drop=(89,4)) gnp
*      @rollreg(add=(71,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.
* DAMP = [1.0]      shape of the spectral window to use with the
*                   ROBUST option.  Note that the default here is a
*                   Newey-West or Bartlett window while in RATS the
*                   default is a flat window (DAMP=0.0).
*
* [PRINT]/NOPRINT   prints the coefficient estimates
* GRAPH/[NOGRAPH]   graphs the test statistics.  At present, the graphs can be
*                   converted to postscript format using the command:
*                   >>gsp2pst chow.gsp post-name<<
*      They can then be printed using the lpr command or viewed
*                   using the postscript viewer.    You must issue the "open
*                   plot" and "close plot" commands from the calling program.
* COPY/[NOCOPY]     writes the estimated coefficients to a file.
*                   You must have already opened the copy unit to this
*                   file
* FORMAT = [FREE]/BINARY/WKS/DIF/PRN/EXCEL/TROLL
*                   for use only with COPY; writes the data in that
*                   format.  Note that ORG=VAR.
*
procedure rollreg  y  first last
type series[real] y
type integer  first last
option integer ADD     0
option integer DROP    0
option integer MOVE    0
option switch robust   0
option real damp      1.0
option integer lags    0
option switch print    1
option switch graph    0
option switch copy     0
option choice format   1 free binary wks dif prn excel troll
local vector[integer] x
local integer fobs lobs numreg base cut k   fbeta lbeta stdbase
local vector[real] xtyt
local rectangular[real] xy
local series[real] m
dis; dis
*
* Define the system to be estimated and initialize
*
enter(varying,entries=numreg) x
inquire(regressorlist) fobs lobs
# y x
if (first .and. last)
    {;  compute fobs=first;   compute lobs=last;    }
dis 'Rolling Regression from' %datelabel(fobs) 'to' %datelabel(lobs) $
    'of ' %label(y) ' on '
dis(hold) '    '
do k=1,numreg
   dis(hold)  %label([series]x(k))  '  '
end do k
dis
make(transpose) xy fobs lobs
# x y
if (add==0)+(drop==0)+(move==0) < 2
    dis 'ROLLREG ERROR: Use only one of ADD, DROP and MOVE options.'
else if .not. (add .or. drop .or. move)
    dis 'ROLLREG ERROR: Must specify one of ADD, DROP and MOVE options.'

else if add
    {
*
* Adding observations to end
*
    dis 'using ADD=' %datelabel(add)
    scratch 2*numreg add lobs base
    cmoment fobs add
    # x y
    linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
    # x
    dofor m = base+1 to base+numreg
        compute m(add) = %beta(m-base)
    end dofor
 if robust == 0
     dofor m=base+1+numreg to base+2*numreg
    compute m(add) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)
     end dofor
 else if robust == 1
    dofor m=base+1+numreg to base+2*numreg
      compute m(add) = sqrt(%xx(m-base-numreg,m-base-numreg))
      end dofor


    do cut=add+1,lobs
 cmoment(setup) fobs cut
 # x y
        overlay xy(1,cut-fobs+1) with xtyt(numreg+1)
        compute %cmom = %cmom + xtyt*tr(xtyt)
        linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
        # x
        dofor m=base+1 to base+numreg
            compute m(cut) = %beta(m-base)
        end dofor
 if robust == 0
         dofor m=base+1+numreg to base+2*numreg
             compute m(cut) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)
         end dofor
 else if robust == 1
  dofor m=base+1+numreg to base+2*numreg
              compute m(cut) = sqrt(%xx(m-base-numreg,m-base-numreg))
         end dofor

    end do cut
    compute fbeta = add; compute lbeta = lobs
    }
else if drop
    {
*
* Dropping observations from start
*
    dis 'using DROP=' %datelabel(drop)
    scratch 2*numreg fobs drop base
    cmoment fobs lobs
    # x y
    linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
    # x
    dofor m=base+1 to base+numreg
        compute m(fobs) = %beta(m-base)
    end dofor
    if robust == 0
     dofor m=base+1+numreg to base+2*numreg
         compute m(fobs) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)

     end dofor
    else if robust == 1
 dofor m=base+1+numreg to base+2*numreg
         compute m(fobs) = sqrt(%xx(m-base-numreg,m-base-numreg))
     end dofor


    do cut=fobs,drop-1
 cmoment(setup) cut+1 lobs
 # x y
        overlay xy(1,cut-fobs+1) with xtyt(numreg+1)
        compute %cmom = %cmom - xtyt*tr(xtyt)
        linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
        # x
        dofor m=base+1 to base+numreg
            compute m(cut+1) = %beta(m-base)
        end dofor
 if robust == 0
        dofor m=base+1+numreg to base+2*numreg
            comptue m(cut+1) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)
        end dofor
 else if robust == 1
 dofor m=base+1+numreg to base+2*numreg
            compute m(cut+1) = sqrt(%xx(m-base-numreg,m-base-numreg))
        end dofor



    end do cut
    compute fbeta = fobs; compute lbeta = drop
    }
else if MOVE
    {
*
* Moving sample regression
*
    dis 'using MOVE=' ### move
    scratch 2*numreg fobs+move-1 lobs base
    cmoment fobs fobs+move-1
    # x y
    linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
    # x
    dofor m=base+1 to base+numreg
        compute m(fobs+move-1) = %beta(m-base)
    end dofor
    if robust == 0
     dofor m=base+1+numreg to base+2*numreg
        compute m(fobs+move-1) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)
     end dofor
    else if robust == 1
  dofor m=base+1+numreg to base+2*numreg
        compute m(fobs+move-1) = sqrt(%xx(m-base-numreg,m-base-numreg))
 end dofor

    do cut=fobs+move,lobs
 cmoment(setup) cut-move+1 cut
 # x y
        overlay xy(1,cut-fobs+1) with xtyt(numreg+1)
        compute %cmom = %cmom + xtyt*tr(xtyt)
        overlay xy(1,cut-move-fobs+1) with xtyt(numreg+1)
        compute %cmom = %cmom - xtyt*tr(xtyt)
        linreg(cmom,noprint,robusterrors=robust,damp=damp,lags=lags) y
        # x
        dofor m=base+1 to base+numreg
            compute m(cut) = %beta(m-base)
        end dofor
 if robust == 0
         dofor m=base+1+numreg to base+2*numreg
            compute m(cut) = sqrt(%xx(m-base-numreg,m-base-numreg)*%seesq)
         end dofor
 else if robust == 1
   dofor m=base+1+numreg to base+2*numreg
            compute m(cut) = sqrt(%xx(m-base-numreg,m-base-numreg))
          end dofor
    end do cut
    compute fbeta = fobs+move-1; compute lbeta = lobs
    }
*
* Now output the results
*
if (add==0)+(drop==0)+(move==0) == 2
{
do k = 1,numreg
    labels base+k base+k+numreg
#  %label([series]x(k)) %concat('se',%label([series]x(k)))
end do k
if print
    print(dates) fbeta lbeta base+1 to base+2*numreg
if copy
    copy(format=format) fbeta lbeta  base+1 to base+2*numreg
if graph
    {
    scratch 2 fbeta lbeta stdbase
    labels stdbase+1 stdbase+2
    # '95%upper' '95%lower'
    do k = base+1, base+numreg
        set stdbase+1 fbeta lbeta = k + (k+numreg)*1.96
        set stdbase+2 fbeta lbeta = k - (k+numreg)*1.96
        if graph
            {
            graph(dates,header='rollreg estimated betas') 3
            # k fbeta lbeta
            # stdbase+1 fbeta lbeta
            # stdbase+2 fbeta lbeta
            }
    end do k
    }
dis 'Coefficients stored in series' ### base+1 'to' ### base+numreg 'and'
dis 'standard errors in series' ### base+numreg+1 'to' ### base+2*numreg

}
*
end proc rollreg
env echo

 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
 *  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.
*
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*



