******************************************************************
* RLINREG series start end *resids
* # <suppl. card>
*
*
* RLINREG computes and graphs recursive coefficient
*   estimates along with 1.96 standard error bands around
*   them, to give a sense whether the coefficients seem
*   constant over a sample.
*
*   RLINREG does this in two ways, controlled by WINDOW =
*     FIXED vs. MOVING
*
*   FIXED estimates the first model using data from start
*     to start+INITIAL-1, and then adds data one period at a time
*     until end is reached.  Since the sample size is increasing
*     the standard error bands will generally tighten as one moves
*     through the sample.  If at a certain date zero is contained w/in
*     the -1.96 and +1.96 standard error bands, one would fail
*     to reject a zero coefficient on that particular variable
*     using that sample.
*
*   MOVING uses a window of constant size, WIDTH, to estimate the
*     coefficients recursively.  So, as one moves through the series,
*     both the beginning and end of the sample are incremented by one.
*     If zero is contained w/in the -1.96 and +1.96 standard error bands,
*     one would fail to reject a zero coefficient on that variable
*     using that particlar sub-sample.
*
*   The residuals saved are the recursive residuals, i.e., other than
*     those from the very beginning (start to start+width or
*     start to start+initial-1) the i-th residual is the
*     residual from the regression whose ending date it t = i.
*     For the first part of the sample (as mentioned above) the
*     residuals are from the preliminary regression from start to
*     start+width or startl+initial-1 -- depending on MOVING vs.
*     FIXED.
*
*   One can use the various ROBUSTERRORS options and INSTRUMENTS
*     which allows one to peform this excersize for a variety of
*     models, not just the simplest linear regression.
*
*
* OPTIONS
*   [GRAPH]/NOGRAPH  Graph (or not) the recursive coefficients
*   KEYPOS = [BELOW]/NONE/UPLEFT/UPRIGHT/LOLEFT/LORIGHT/ABOVE/LEFT/RIGHT
*                 Controls if and where a Key is included on the graph.
*
*   WINDOW =  [FIXED]/MOVING  Whether the window keeps the same
*                    beginning or not as one moves throughout the
*                    sample
*   INITIAL = [20]   With FIXED, determines how large the sample
*                    the initial estimate will use (initial-1)
*   WIDTH =   [30]   With MOVING, determine how large the constant-
*                    sized window will be as it moves thorough the
*                    series
*   ROBUSTERRORS/[NOROBUSTERRORS]  |  Allows one to use robusterrors
*      DAMP =  [0]                 |   to calculate the standard
*      LAGS =  [0]                 |   error bands
*
*   INSTRUMENTS/[NOINSTRUMENTS]    |  Allows one to use instrumental
*                                  |   variables
*
*
**  The coefficients are saved in the vector of series   *
**      COEFFS, the + and - 1.96 standard errors around  *
**      the coefficients are saved in SEP and SEM.       *
*
*
*   By Norman Morin, nmorin@frb.gov
*      v1   11/97
*      v2   3/16/98  Fixed missing value bug, by Tom Maycock
*
*******************************************************************

DECL VECT[series]  coeffs sep sem

PROCEDURE RLINREG series start end resids

TYPE SERIES *series *resids
TYPE INTEGER start end

OPTION SWITCH GRAPH 1
OPTION CHOICE WINDOW 1 FIXED MOVING
OPTION CHOICE KEYPOS 7 NONE UPLEFT UPRIGHT LOLEFT LORIGHT ABOVE BELOW LEFT RIGHT
OPTION INTEGER INITIAL 20
OPTION INTEGER WIDTH 20
OPTION INTEGER LAGS 0
OPTION INTEGER DAMP 0
OPTION SWITCH ROBUSTERRORS 0
OPTION SWITCH INSTRUMENTS 0


LOCAL INTEGER nx startl endl
LOCAL SERIES resid
LOCAL VECT[LABELS]  xlabel sepl seml coeffl
LOCAL INDEX xlist


ENTER(varying) xlist

IF .NOT.%DEFINED(SERIES) {
   DISPLAY 'Syntax: @RLINREG series start end resids'
   RETURN
}

INQUIRE(series=series) startl>>start endl>>end


* Assign labels:
SET depvar startl startl = 1.0
EQUATION dummyeq depvar
# xlist
COMPUTE eqnarray = %eqntable(dummyeq)
compute nx = %cols(eqnarray)

DIM xlabel(nx) sepl(nx) seml(nx) coeffl(nx)

DO i = 1,nx
   IF eqnarray(2,i)>0
      COMPUTE xlabel(i) = $
         %label( [series] eqnarray(1,i) )+'{'+eqnarray(2,i)+'}'
   ELSE
      COMPUTE xlabel(i) = %label([series] eqnarray(1,i))
   COMPUTE sepl(i) = '+1.96 Std. Err.'
   COMPUTE seml(i) = '-1.96 Std. Err.'
   COMPUTE coeffl(i) = xlabel(i)
END DO

/*
DO i = 1,nx
   LABELS xseries(i)
   #xlabel(i)
END DO
*/
DIM coeffs(nx) sep(nx) sem(nx)

IF WINDOW.eq.1 {
 DO i = 1,nx
   SET coeffs(i) startl+initial endl  = 0.
   SET sep(i) startl+initial endl = 0.
   SET sem(i) startl+initial endl = 0.
 END DO
}
ELSE {
 DO i = 1,nx
   SET coeffs(i) startl+width+1 endl  = 0.
   SET sep(i) startl+width+1 endl = 0.
   SET sem(i) startl+width+1 endl = 0.
 END DO
}

DO i = 1,nx
   LABELS coeffs(i) sep(i) sem(i)
   # coeffl(i) sepl(i) seml(i)
END DO

IF WINDOW.eq.1 {

  SET resid startl endl = 0.
  LINREG(noprint) series startl startl+initial-1 res
  #xlist
*  #xseries
  SET resid startl startl+initial-1 = res
  DO i = 1,endl-initial-startl+1
    LINREG(noprint,robusterrors=robusterrors,lags=lags,damp=damp, $
       instuments=instruments) $
       series startl startl+initial+i-1 res
   #xlist
*  #xseries
    COMPUTE resid(startl+initial+i-1) = res(startl+initial+i-1)
    IF ROBUSTERRORS.eq.1
       COMPUTE %seesq = 1.
    DO j = 1,nx
       COMPUTE coeffs(j)(startl+initial+i-1) = %beta(j)
       COMPUTE sep(j)(startl+initial+i-1) = %beta(j)+1.96*sqrt(%seesq*%xx(j,j))
       COMPUTE sem(j)(startl+initial+i-1) = %beta(j)-1.96*sqrt(%seesq*%xx(j,j))
    END DO
  END DO

  IF GRAPH.eq.1 {
   DO i = 1,nx
*     DISPLAY(STORE=HEADER) 'Recursive estimates of' %LABEL(xseries(i))
     DISPLAY(STORE=HEADER) 'Recursive estimates of' xlabel(i)
     GRAPH(header=header,key=keypos) 3
     # coeffs(i) startl+initial endl
     # sep(i)   startl+initial endl 2
     # sem(i)   startl+initial endl 2
   END DO
  }

  IF %DEFINED(resids)
    SET resids startl endl = resid

}

ELSE IF WINDOW.eq.2 {

  SET resid startl endl = 0.
  LINREG(noprint) series startl startl+width res
  #xlist
*  #xseries
  SET resid startl startl+width = res
  DO i = 1,endl-startl-width
    LINREG(noprint,robusterrors=robusterrors,lags=lags,damp=damp, $
       instuments=instruments) $
       series startl+i startl+width+i res
  #xlist
*  #xseries
    COMPUTE resid(startl+width+i) = res(startl+width+i)
    IF ROBUSTERRORS.eq.1
       COMPUTE %seesq = 1.
    DO j = 1,nx
       COMPUTE coeffs(j)(startl+width+i) = %beta(j)
       COMPUTE sep(j)(startl+width+i) = %beta(j)+1.96*sqrt(%seesq*%xx(j,j))
       COMPUTE sem(j)(startl+width+i) = %beta(j)-1.96*sqrt(%seesq*%xx(j,j))
    END DO
  END DO

  IF GRAPH.eq.1 {
   DO i = 1,nx
*     DISPLAY(STORE=HEADER) 'Recursive estimates of' %LABEL(xseries(i))
     DISPLAY(STORE=HEADER) 'Recursive estimates of' xlabel(i)
     DISPLAY(STORE=SUBHEADER) 'Using a moving window of width' width
     GRAPH(header=header,subheader=subheader,key=keypos) 3
     # coeffs(i) startl+width+1 endl
     # sep(i)   startl+width+1 endl 2
     # sem(i)   startl+width+1 endl 2
   END DO
  }

  IF %DEFINED(resids)
    SET resids startl endl = resid

}
END













