*******************************************************************************
* PROCEDURE LAGSELECT series start end
* # <suppl. card>  optional exogenous variables in regression format
*
* OPTIONS
*     CRIT = AIC/BIC/LB/LM/GS/[All] Criteria for determining lag length
*     DET = NONE/[CONSTANT]/TREND   Deterministic components in the regression
*     EXOG/[NOEXOG]                 Include optional exogenous variables
*                                     in suppl. card in regression format
*     SCLAG [24]                    Order for LB/LM tests
*                                     forced to be >= 1.5*maxlag
*     SIGNIF [0.05]                 Significance level for tests
*     MAXLAG [16]                   Maximium lag for AIC/BIC
*     [PRINT]/NOPRINT               Print results
*
* LAGSELECT determines the optimal lag length for a series using
*     one of or all of five criteria:
*
*     (1) [AIC] AIC model selection criterion
*     (2) [BIC] BIC model selection criterion
*                 (The BIC is also called the Schwarz criterion)
*     (3) [LB]  Ljung-Box test for residual serial correlation
*     (4) [LM]  Lagrange multiplier (LM) test for residual serial correlation
*     (5) [GS]  General-to-simple (GS) reduction test
*     (6) [All] Calculates lag lengths by all five criteria
*
*   (1) and (2) perform regressions from 0 to MAXLAG lags and chooses
*       the optimal lag length by the minimum AIC or BIC.
*   (3) and (4) adds lags until the Ljung-Box test (3) or the Lagrange
*       multiplier test (4) fails to reject no serial correlation of
*       order SCLAG at a user defined level (SIGNIF) or until lag = MAXLAG.
*   (5) starts with MAXLAG lags, and if the final lag is significant (at the
*       level SIGNIF), that lag length is chosen; if not, the lag length
*       is continually reduced until either the last included lag is
*       significant or no lags are included.
*
*   The lag lengths chosen by the criteria are saved to
*           lagaic, lagbic, laglb, laglm, lags
*   If only one criterion is chosen with the CRIT option, the
*   other lag integers are set to zero; e.g., if CRIT = LM is
*   chosen, laglm will equal the smallest lag length for which
*   the LM test for residual serial correlation is insignificant,
*   and lagaic, lagbic, laglb, and laggs will be set to zero.
*
*
*  By Norman Morin, nmorin@frb.gov, April 1998
*
*    Revised 9/8/99:   Fixed call to SELECTUNI for DET=CONSTANT case (previously
*                      included a TREND for both DET=TREND and DET=CONSTANT).
*    Revised 10/31/03: Added code to zero out LAGAIC if BIC is selected or
*                      vice versa, to conform with comments above.
*
******************************************************************************
* EXAMPLE:  Output from the growth rate of GDP, 1947:1 to 1997:3
*
* @LAGSELECT(maxlag=8,sclags=12,det=constant,signif=.05) delg
*
* ********************************************
* *  Determining the optimal lag length for  *
* *         DELG                             *
* ********************************************
*
*
* Model Selection Criteria
*
*   Minimum AIC at lag:     5
*   Minimum BIC at lag:     1
*
*   Lag         AIC            BIC
*     0      -9.08037       -9.04668
*     1      -9.18288       -9.13235
*     2      -9.17702       -9.10964
*     3      -9.17388       -9.08966
*     4      -9.18332       -9.08225
*     5      -9.18409       -9.06618
*     6      -9.17378       -9.03902
*     7      -9.16556       -9.01396
*     8      -9.15943       -8.99099
*
*
* Ljung-Box test for residual serial correlation of order 12
*
*   Adding lag 0
*      Test Statistic:   48.96707   Significance Level: 0.00000
*   Adding lag 1
*      Test Statistic:   13.58545   Significance Level: 0.19275
*
*
* Lagrange multiplier test for residual serial correlation of order 12
*
*   Adding lag 0
*      Test Statistic:   40.00513   Significance Level: 0.00007
*   Adding lag 1
*      Test Statistic:   14.45547   Significance Level: 0.27257
*
*
* General-to-Simple lag specification
*
*    Significance of lag  8 :  0.52772
*    Significance of lag  7 :  0.62654
*    Significance of lag  6 :  0.81580
*    Significance of lag  5 :  0.18555
*    Significance of lag  4 :  0.07606
*    Significance of lag  3 :  0.23951
*    Significance of lag  2 :  0.27221
*    Significance of lag  1 :  0.00000
*
*
*
* ******************************************
* Criterion             Suggested Lag Length
*   AIC                            5
*   BIC                            1
*   Ljung-Box Test                 1
*   Lagrange Multiplier Test       1
*   General to Simple              1
* ******************************************
*
*******************************************************************************
*******************************************************************************

DECLARE INTEGER lagaic lagbic laglb laglm laggs
*******************************************************************************
****  Performs the Ljung-Box Tests
PROCEDURE LB series start end

TYPE SERIES      series
TYPE INTEGER     start end

OPTIONS INTEGER  LAGS   16
OPTIONS INTEGER  DFC     0
OPTIONS SWITCH   PRINT   1

LOCAL INTEGER    startl endl spanl count nobs num
LOCAL SERIES     corr corr2 csum TREND

INQUIRE(series=series) startl>>start endl>>end
COMPUTE nobs = endl - startl + 1

IF (dfc.ge.lags)
    COMPUTE num = fix(1.5*dfc)
ELSE
    COMPUTE num = lags

CORRELATE(noprint,number=num) series startl endl corr

SET TREND = t
SET corr2 1 num+1 = corr**2/(nobs-trend)
SET csum 1 num = 0

ACCUMULATE corr2 2 num+1 csum 1

COMPUTE LBSTAT = nobs*(nobs+2)*csum(num)
COMPUTE LBSIGNIF = %CHISQR(LBSTAT,num-dfc)

IF PRINT.eq.1 {
   DISP '      Test Statistic:' ####.##### LBSTAT '  Significance Level:' $
               #.##### LBSIGNIF
  }

END
*******************************************************************************

*******************************************************************************
****  Performs the Lagrange Multiplier tests
PROCEDURE SCTEST depvar start end

TYPE SERIES      depvar
TYPE INTEGER     start end

OPTION INTEGER   lags     4
OPTION SWITCH    print    1

LOCAL SERIES     resids
LOCAL INDEX      reglist
LOCAL INTEGER    startl endl

ENTER(varying) reglist
INQUIRE(regressorlist)  startl>>start  endl>>end
#depvar reglist

LINREG(noprint) depvar startl endl resids
#reglist

LINREG(noprint,dfc=%nreg) resids startl+lags endl
#reglist resids{1 to lags}

IF (%RSQUARED.lt.0) {
COMPUTE %TRSQ = 0., SCSIGNIF = 1.
  IF PRINT.eq.1 {
    DISP '      Test Statistic:' ####.##### %TRSQ '  Significance Level:' $
                  #.#####  SCSIGNIF
  }
}

ELSE {
COMPUTE SCSIGNIF=%CHISQR(%TRSQ,LAGS)
  IF PRINT.eq.1 {
    DISP '      Test Statistic:' ####.##### %TRSQ '  Significance Level:' $
                  #.##### SCSIGNIF
   }
}

END
*******************************************************************************

*******************************************************************************
****  Finds the minimum AIC and BIC
PROCEDURE SELECTUNI series start end

TYPE     series       series
OPTION   integer      number  20
OPTION   choice       det      2    none constant trend
OPTION   switch       exog     0
OPTION   switch       print    1

LOCAL INTEGER maxlag lagnum i startl endl nx
LOCAL SERIES aic bic series trend delseries
LOCAL REAL aico bico
LOCAL INDEX xlist
LOCAL VECT[series] xseries
LOCAL RECT xmat

INQUIRE(series=series) startl>>start endl>>end
COMPUTE  nobs = endl-startl+1

IF (EXOG.eq.1) {
   ENTER(varying) xlist
   MAKE XMAT startl endl
   # xlist
   COMPUTE nx = %cols(xmat)
   DIM XSERIES(nx)
   DO i = 1,nx
      SET XSERIES(i) startl endl =  XMAT(t-startl+1,i)
   END DO
  }

SET delseries startl endl = series - series{1}

COMPUTE maxlag = number

IF startl<=maxlag
 {
   compute startl = maxlag+1
*   display 'Adjusting start date to ' %datelabel(startl+1) ' to allow'
*  display ' for specified maximum lag length of ' maxlag ' lags.'
*   display 'Use the MAXLAG option to set a different max. lag length.'
 }


IF EXOG.eq.0 {
  IF (det.eq.1)
     {

     CMOM startl endl
     #series{0 to maxlag}

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag = 0.

     LINREG(cmom,noprint) series startl endl
     #

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
          LINREG(cmom,noprint) series startl endl
          #series{1 to lagnum}
          COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
          COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }

  ELSE IF (det.eq.2)
     {
     CMOM startl endl
     #constant series{0 to maxlag}

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag  = 0.

     LINREG(noprint,cmom) series startl endl
     #constant

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
        LINREG(cmom,noprint) series startl endl
        #constant series{1 to lagnum}
        COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
        COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }

  ELSE
     {
    SET TREND = T
     CMOM startl endl
     #constant trend series{0 to maxlag}

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag  = 0.

     LINREG(noprint,cmom) series startl endl
     #constant trend

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
        LINREG(cmom,noprint) series startl endl
        #constant trend series{1 to lagnum}
        COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
        COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }


 }


ELSE IF EXOG.eq.1 {

  IF (det.eq.1)
     {

     CMOM startl endl
     #series{0 to maxlag} xlist

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag = 0.

     LINREG(cmom,noprint) series startl endl
     #xlist

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
          LINREG(cmom,noprint) series startl endl
          #series{1 to lagnum} xlist
          COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
          COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }

  ELSE IF (det.eq.2)
     {
     CMOM startl endl
     #constant series{0 to maxlag} xlist

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag  = 0.

     LINREG(noprint,cmom) series startl endl
     #constant xlist

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
        LINREG(cmom,noprint) series startl endl
        #constant series{1 to lagnum} xlist
        COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
        COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }

  ELSE
     {
    SET TREND = T
     CMOM startl endl
     #constant trend series{0 to maxlag} xlist

     SET aic 1 maxlag  = 0.
     SET bic 1 maxlag  = 0.

     LINREG(noprint,cmom) series startl endl
     #constant trend xlist

     COMPUTE aico = log(%rss/%nobs) + 2.*%nreg/%nobs
     COMPUTE bico = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)

     DO lagnum = 1,maxlag
        LINREG(cmom,noprint) series startl endl
        #constant trend series{1 to lagnum} xlist
        COMPUTE aic(lagnum) = log(%rss/%nobs) + 2.*%nreg/%nobs
        COMPUTE bic(lagnum) = log(%rss/%nobs) + (1.*%nreg/%nobs)*log(%nobs)
     END DO
     }
 }
*IF PRINT.eq.1 {
*  DISP
*  DISP 'Model Selection Criteria'
*  DISP
*}

* print 1 maxlag aic
EXTREMEUM(noprint)  aic 1 maxlag

IF (%MINIMUM.lt.aico) {
*  IF PRINT.eq.1
*     DISP '   Minimum AIC at lag:' @26 ## %MINENT
  COMPUTE lagaic = %MINENT
     }
ELSE {
*  IF PRINT.eq.1
*     DISP '   Minimum AIC at lag:' @27 '0'
  COMPUTE lagaic = 0
     }

EXTREMEUM(noprint) bic 1 maxlag
IF (%MINIMUM.lt.bico) {
*  IF PRINT.eq.1
*     DISP '   Minimum BIC at lag:' @26 ## %MINENT
  COMPUTE lagbic = %MINENT
     }
ELSE {
*  IF PRINT.eq.1
*     DISP '   Minimum BIC at lag:' @27 '0'
  COMPUTE lagbic = 0
     }

*IF PRINT.eq.1 {
*  DISP
*  DISP '   Lag'  @15 'AIC' @30 'BIC'
*  DISP '     0'  @11 ###.##### aico @26 ###.##### bico
*  DO i = 1,maxlag
*    DISP @3 ### i   @11 ###.##### aic(i) @26 ###.##### bic(i)
*  END DO
* }

END SELECTUNI
*****************************************************************************

*****************************************************************************
PROCEDURE LAGSELECT series start end

TYPE SERIES series
TYPE INTEGER start end

OPTION CHOICE   CRIT 6 AIC BIC LB LM GS ALL
OPTION CHOICE   DET 2 NONE CONSTANT TREND
OPTION SWITCH   EXOG 0
OPTION INTEGER  SCLAG 24
OPTION REAL     SIGNIF 0.05
OPTION INTEGER  MAXLAG 13
OPTION SWITCH   PRINT 1


LOCAL REAL    signf sig signif
LOCAL INTEGER laglb laglm laggs ml
LOCAL INTEGER lag maxlag sclags startl endl crits dets maxlags nx i
LOCAL SERIES  trend resids depvar
LOCAL INDEX   xlist
LOCAL RECT    XMAT
LOCAL RECT[INT]  eqnarray
LOCAL VECT[series] xseries
LOCAL VECT[label] xlabel

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

IF (EXOG.eq.1) {
   ENTER(varying) xlist
   MAKE XMAT startl endl
   # xlist
   COMPUTE nx = %cols(xmat)
   DIM XSERIES(nx)
   DO i = 1,nx
      SET XSERIES(i) startl endl =  XMAT(t-start+1,i)
   END DO

   DIM xlabel(nx)

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

   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))
   END DO
   DO i = 1,nx
     lables xseries(i)
     #xlabel(i)
   END DO
 }

ELSE {
   COMPUTE nx = 0
  }

COMPUTE lagaic = fix(%NA), lagbic = fix(%NA), laglb = fix(%NA), $
  laglm = fix(%NA), laggs = fix(%NA)


IF %DEFINED(SIGNIF)
  COMPUTE signf = SIGNIF
ELSE
  COMPUTE signf = 0.05
IF %DEFINED(MAXLAG)
  COMPUTE maxlags = MAXLAG
ELSE
  COMPUTE maxlags = 13
IF %DEFINED(DET)
  COMPUTE DETS = DET
ELSE
  COMPUTE DETS = 2
IF %CLOCK(fix(1.5*maxlags),2).eq.1
  COMPUTE ML = fix(1.5*maxlags)+1
ELSE
  COMPUTE ML = fix(1.5*maxlags)
COMPUTE SCLAGS = %imax(sclag,ML)


IF PRINT.eq.1
 {
  DISP
  DISP '********************************************'
  DISP '*  Determining the optimal lag length for  *'
  DISP '*        ' %LABEL(series)  @43 '*'
  IF EXOG.eq.1 {
     DISPLAY '*     w/' nx 'exogenous variables' @43 '*'
     DO i = 1,nx
        DISPLAY '*        ' XLABEL(i) @43 '*'
     END DO
  }
  DISP '********************************************'
  DISP
 }


*** AIC & BIC

IF CRIT.eq.1.or.CRIT.eq.2.or.CRIT.eq.6 {
 IF EXOG.eq.0 {
   IF (dets.eq.1) {
*       @SELECTUNI(number=maxlags,dets=none,print=print) series startl endl
        @SELECTUNI(number=maxlags,dets=none) series startl endl

        }
   ELSE IF (dets.eq.2) {
*      @SELECTUNI(number=maxlags,dets=constant,print=print) series startl endl
       @SELECTUNI(number=maxlags,dets=constant) series startl endl
       }
   ELSE IF (dets.eq.3) {
      SET TREND = T
*      @SELECTUNI(number=maxlags,dets=trend,print=print) series startl endl
      @SELECTUNI(number=maxlags,dets=trend) series startl endl

      }
    }

 ELSE IF EXOG.eq.1  {
   IF (dets.eq.1) {
*     @SELECTUNI(number=maxlags,dets=none,exog,print=print) series startl endl
	 @SELECTUNI(number=maxlags,dets=none,exog) series startl endl

     #xlist
        }
   ELSE IF (dets.eq.2) {
*     @SELECTUNI(number=maxlags,dets=constant,exog,print=print) series startl endl
      @SELECTUNI(number=maxlags,dets=constant,exog) series startl endl

     #xlist
       }
   ELSE IF (dets.eq.3) {
     SET TREND = T
*     @SELECTUNI(number=maxlags,dets=trend,exog,print=print) series startl endl
     @SELECTUNI(number=maxlags,dets=trend,exog) series startl endl

     #xlist
      }
   }
 }



*** Ljung-Box Test

IF CRIT.eq.3.or.CRIT.eq.6 {

 IF PRINT.eq.1 {
   DISP ; DISP
   DISP 'Ljung-Box test for residual serial correlation of order ' $
                  @-1 sclags
   DISP
  }

 COMPUTE lag = 0; COMPUTE sig = 0.0;
 IF (dets.eq.2).and.EXOG.eq.0 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
           LINREG(noprint) series startl endl resids
           #constant series{1 to lag}
     ELSE
        LINREG(noprint) series startl endl resids
           #constant
     @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl
           COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
   }

 ELSE IF (dets.eq.2).and.EXOG.eq.1 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
           LINREG(noprint) series startl endl resids
           #constant series{1 to lag} xlist
     ELSE
        LINREG(noprint) series startl endl resids
           #constant xlist
     @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl
     COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
   }

 ELSE IF (dets.eq.3).and.EXOG.eq.0 {
   SET TREND startl endl = T
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
        LINREG(noprint) series startl endl resids
        #constant trend series{1 to lag}
     ELSE
        LINREG(noprint) series startl endl resids
        #constant trend
     @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl
     COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
   }

 ELSE IF (dets.eq.3).and.EXOG.eq.1 {
   SET TREND startl endl = T
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
        LINREG(noprint) series startl endl resids
        #constant trend series{1 to lag} xlist
     ELSE
        LINREG(noprint) series startl endl resids
        #constant trend xlist
     @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl
     COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
   }

 ELSE IF (dets.eq.1).and.EXOG.eq.0 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

      IF (lag.gt.0)
         LINREG(noprint) series startl endl resids
         #series{1 to lag}
      ELSE
         LINREG(noprint) series startl endl resids
         #
      @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl series
      COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
   }

 ELSE IF (dets.eq.1).and.EXOG.eq.1 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

      IF (lag.gt.0)
         LINREG(noprint) series startl endl resids
         #series{1 to lag} xlist
      ELSE
         LINREG(noprint) series startl endl resids
         #  xlist
      @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl series
      COMPUTE sig = lbsignif

     IF (sig.gt.signf)
       COMPUTE laglb = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglb = lag
       }
     }
  }
 }


** Lagrange Multiplier Test

IF CRIT.eq.4.or.CRIT.eq.6 {
 IF PRINT.eq.1 {
   DISP ; DISP
   DISP 'Lagrange multiplier test for residual serial correlation of order ' $
                 @-1 sclags
   DISP
   }

 COMPUTE lag = 0; COMPUTE sig = 0.0
 IF (dets.eq.2).and.EXOG.eq.0 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
           LINREG(noprint) series startl endl resids
           #constant series{1 to lag}
     ELSE
        LINREG(noprint) series startl endl resids
           #constant

     IF (lag.gt.0) {
         @SCTEST(print=print,lags=sclags) series startl endl
         #constant series{1 to lag}
         COMPUTE sig = scsignif
         }
     ELSE {
         @SCTEST(print=print,lags=sclags) series startl endl
         #constant
         COMPUTE sig = scsignif
         }

     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
     }
   }

 ELSE IF (dets.eq.2).and.EXOG.eq.1 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
           LINREG(noprint) series startl endl resids
           #constant series{1 to lag} xlist
     ELSE
        LINREG(noprint) series startl endl resids
           #constant xlist

     IF (lag.gt.0) {
         @SCTEST(print=print,lags=sclags) series startl endl
         #constant series{1 to lag} xlist
         COMPUTE sig = scsignif
         }
     ELSE {
         @SCTEST(print=print,lags=sclags) series startl endl
         #constant xlist
         COMPUTE sig = scsignif
         }


     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
   }
  }

 ELSE IF (dets.eq.3).and.EXOG.eq.0 {
   SET TREND startl endl = T
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
        LINREG(noprint) series startl endl resids
        #constant trend series{1 to lag}
     ELSE
        LINREG(noprint) series startl endl resids
        #constant trend
      IF (crits.eq.2) {
        @LB(print=print,lags=sclags,dfc=lag+1) resids startl endl
        COMPUTE sig = lbsignif
       }

     IF (lag.gt.0) {
       @SCTEST(print=print,lags=sclags) series startl endl
       #constant trend series{1 to lag}
       COMPUTE sig = scsignif
        }
     ELSE {
       @SCTEST(print=print,lags=sclags) series startl endl
       #constant trend
       COMPUTE sig = scsignif
       }

     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
   }
  }

 ELSE IF (dets.eq.3).and.EXOG.eq.1 {
   SET TREND startl endl = T
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

     IF (lag.gt.0)
        LINREG(noprint) series startl endl resids
        #constant trend series{1 to lag} xlist
     ELSE
        LINREG(noprint) series startl endl resids
        #constant trend xlist

     IF (lag.gt.0) {
       @SCTEST(print=print,lags=sclags) series startl endl
       #constant trend series{1 to lag} xlist
       COMPUTE sig = scsignif
        }
     ELSE {
       @SCTEST(print=print,lags=sclags) series startl endl
       #constant trend xlist
       COMPUTE sig = scsignif
       }

     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
    }
  }

 ELSE IF (dets.eq.1).and.EXOG.eq.0 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

      IF (lag.gt.0)
         LINREG(noprint) series startl endl resids
         #series{1 to lag}
      ELSE
         LINREG(noprint) series startl endl resids
         #

     IF (lag.gt.0) {
       @SCTEST(print=print,lags=sclags) series startl endl
       #series{1 to lag}
       COMPUTE sig = scsignif
         }
     ELSE {
       @SCTEST(print=print,lags=sclags) series startl endl
       #
       COMPUTE sig = scsignif
         }


     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
    }
   }

 ELSE IF (dets.eq.1).and.EXOG.eq.1 {
   WHILE (sig.lt.signf).and.(lag.lt.maxlags) {
     IF PRINT.eq.1
       DISP '   Adding lag' lag

      IF (lag.gt.0)
         LINREG(noprint) series startl endl resids
         #series{1 to lag} xlist
      ELSE
         LINREG(noprint) series startl endl resids
         #  xlist

      IF (lag.gt.0) {
       @SCTEST(print=print,lags=sclags) series startl endl
       #series{1 to lag} xlist
       COMPUTE sig = scsignif
         }
      ELSE {
       @SCTEST(print=print,lags=sclags) series startl endl
       # xlist
       COMPUTE sig = scsignif
       }

     IF (sig.gt.signf)
       COMPUTE laglm = lag
     ELSE   {
       COMPUTE lag = lag + 1
       COMPUTE laglm = lag
       }
   }
  }

}


*** General to Simple

IF CRIT.eq.5.or.CRIT.eq.6 {
 IF PRINT.eq.1 {
   DISP ; DISP
   DISP 'General-to-Simple lag specification '
   DISP
   }

 IF EXOG.eq.0 {
  SET TREND startl endl = T
  COMPUTE %signif = 1.0
  COMPUTE lag = maxlags
  WHILE (SIGNIF.lt.%signif) {

     IF (dets.eq.1) {

        IF (lag.eq.0) {
          LINREG(noprint) series startl endl
          #
          COMPUTE %signif = 0.0
          }
        ELSE {
          LINREG(noprint) series startl endl
          #series{1 to lag}
          Exclude(noprint) ; #series{lag}
          }
        }

     ELSE IF (dets.eq.2) {

        IF (lag.eq.0) {
          LINREG(noprint) series startl endl
          #constant
          COMPUTE %signif = 0.0
        }
        ELSE {
          LINREG(noprint) series startl endl
          #constant series{1 to lag}
          Exclude(noprint) ; #series{lag}
        }
      }

     ELSE   {
       IF (lag.eq.0) {
         LINREG(noprint) series  startl endl
         # constant trend
         COMPUTE %signif = 0.0
         }
       ELSE {
         LINREG(noprint) series  startl endl
         #constant trend series{1 to lag}
         Exclude(noprint) ; #series{lag}
         }
        }

     IF (lag.gt.0) {
       IF PRINT.eq.1
           DISP '   Significance of lag' @23 ## lag ':' ##.##### %signif
       IF (SIGNIF.lt.%signif)
       COMPUTE lag = lag - 1
       COMPUTE laggs = lag
       }
     ELSE {
       IF PRINT.eq.1
         DISP '   No lags are significant in the regression'
       COMPUTE laggs = 0
       }

     }     **** End WHILE
    }

 ELSE IF EXOG.eq.1 {
   SET TREND startl endl = T
   COMPUTE %signif = 1.0
   COMPUTE lag = maxlags
   WHILE (SIGNIF.lt.%signif) {

     IF (dets.eq.1) {

        IF (lag.eq.0) {
          LINREG(noprint) series startl endl
          #xlist
          COMPUTE %signif = 0.0
          }
        ELSE {
          LINREG(noprint) series startl endl
          #series{1 to lag} xlist
          Exclude(noprint) ; #series{lag}
          }
        }

     ELSE IF (dets.eq.2) {

        IF (lag.eq.0) {
          LINREG(noprint) series startl endl
          #constant xlist
          COMPUTE %signif = 0.0
        }
        ELSE {
          LINREG(noprint) series startl endl
          #constant series{1 to lag} xlist
          Exclude(noprint) ; #series{lag}
        }
      }

     ELSE   {
       IF (lag.eq.0) {
         LINREG(noprint) series  startl endl
         # constant trend xlist
         COMPUTE %signif = 0.0
         }
       ELSE {
         LINREG(noprint) series  startl endl
         #constant trend series{1 to lag} xlist
         Exclude(noprint) ; #series{lag}
         }
        }

     IF (lag.gt.0) {
       IF PRINT.eq.1
           DISP '   Significance of lag' @23 ## lag ':' ##.##### %signif
       IF (SIGNIF.lt.%signif)
       COMPUTE lag = lag - 1
       COMPUTE laggs = lag
       }
     ELSE {
       IF PRINT.eq.1
         DISP '   No lags are significant in the regression'
       COMPUTE laggs = 0
       }

     }     **** End WHILE

   }

 }

*
* Need to zero out AIC if BIC chosen explicitly, or vice versa
* per the description at the top of the procedure:

IF CRIT.eq.1
 compute lagbic = 0
if CRIT.eq.2
 compute lagaic = 0

IF PRINT.eq.1 {
  DISP; DISP ; DISP
  DISP '******************************************'
  DISP 'Criterion'            @22 'Suggested Lag Length'
  IF CRIT.eq.1.or.CRIT.eq.6
    DISP '  AIC'                        @31 ### lagaic
  IF CRIT.eq.2.or.CRIT.eq.6
    DISP '  BIC'                        @31 ### lagbic
  IF CRIT.eq.3.or.CRIT.eq.6
    DISP '  Ljung-Box Test'             @31 ### laglb
  IF CRIT.eq.4.or.CRIT.eq.6
    DISP '  Lagrange Multiplier Test'   @31 ### laglm
  IF CRIT.eq.5.or.CRIT.eq.6
    DISP '  General to Simple '         @31 ### laggs
  DISP '******************************************'
  DISP
 }


END LAGSELECT














