env noecho
*
* RESDIAG.SRC       by Robert Amano and Simon van Norden    02-07-91
* Copyright 1993, 1991 by Bank of Canada
* (modified for RATS v4 August 1993 by Jeff Gable)
*
* This procedure calculates a number of residual diagnostic tests
*
* The syntax for the procedure is
* @RESDIAG(options) residuals
* # list of series
* # dependent_variable fitted_values   
*  (the last card is used with the RESET option only)
*
* where
*   residuals       = the name of the residual series
*   list of series  = the variables used in your regression
*
* We assume that the list of regressors supplied by the user includes a CONSTANT
* as the first series in the list.
*
*  NOTE: that on the supplementary card you cannot use the usual RATS notation
*        for leads and lags (eg. X{0 to 2}).  If you use leads or lags in your 
*        model, you have two choices:
*        
*        1. Turn the LM and Breusch-Pagan test off (ie NOLMP, NOBPHET) and 
*           leave the reset test off.  The procedure will still calculate all 
*           other test statistics.
*        OR
*        2. Code each one into a new unlagged variable, then list the new
*           variable on the supplementary card.  Eg. set X1 = X(t-1)
*                                                    etc.
*                                                    @resdiag resid
*                                                    # constant X X1 ...
* options:
*    [PRINT]/NOPRINT        Prints the series autocorrelations and partial-
*                           autocorrelations up to LBQDOF (see below)
*    LBQTEST=[season freq.] Does Ljung-Box Q-tests for serial correlation 
*                           up to the LBQTESTth order
*    LBQDOF=[0]             Degrees of freedom correction for above test.  If
*                           the residuals are from an estimated ARMA(p,q), use
*                           QDOF=p+q
*    [LMP]/NOLMP            LM tests for serial correlation
*    LMTEST=[season freq.]  sets the LM test to the seasonal frequency of
*                           the data
*    [LMLOOP]/NOLMLOOP      tests up to the LMTESTth order of serial
*                           correlation
*    ARTEST=[season freq.]  sets the simple and restricted AR test to the
*                           seasonal frequency of the data
*    [ARLOOP]/NOARLOOP      tests up to the ARth order of simple serial
*                           correlation
*    [WALLIS]/NOWALLIS      performs the Wallis test for fourth order serial
*                           correlation
*    TESTARCH=[1]           sets the order of the ARCH test
*    [LOOPARCH]/NOLOOPARCH  tests up to the TESTARCHth order of ARCH
*    [BPHET]/NOBPHET        tests the modified Breusch-Pagan
*    RESET/[NORESET]        To do the RESET test, users must specify
*                           the RESET option and supply a second supplementary 
*                           card listing the dependent variable and the model's
*                           fitted values(RESET is appropriate only for models
*                           estimated with OLS).
*
*
procedure resdiag  residual  first last
type series[real] residual
type integer first last
option switch print      1
option integer lbqtest   0
option integer lbqdof    0
option integer lmtest    0
option switch  lmloop    1
option switch  lmp       1
option integer artest    0
option switch  arloop    1
option switch  wallis    1
option integer testarch  0
option switch  looparch  1
option switch  reset     0
option switch  bphet     1
local  integer  fobs lobs nregs lm arch base k j p ar pos neg run zero lbq
local  vector[integer]  reglist rsetlist
local  series[real]  resid2 pfxsq pfxcub pfxqua resnum resden prsd
local  vector[real]  residmom
local  rectangular[real]  newspace
local  real  chistat d4 Zrun Zsign lbqstat
dis; dis
*
inquire(series=residual) fobs lobs
if (first .and. last)
    {;  compute fobs=first;   compute lobs=last;    }
enter(varying,entries=nregs) reglist
dis 'Analyzing residuals in series ' %label(residual) $
        ' from ' %datelabel(fobs) ' to ' %datelabel(lobs)
dis '    using the following series:'
dis(hold) '    '
do j=1,nregs
   dis(hold) %label([series]reglist(j))  '  '
end do j
dis;dis;dis
*
* Durbin-Watson Statistic
*
linreg(noprint) residual fobs lobs
# constant
* Results displayed below under Ljung-Box Q-statistic 
* 
* Ljung-Box Q-Statistic
*
if lbqtest == 0
   compute lbq = %cal(%year(1)+1,1) - %cal(%year(1),1) 
else
   compute lbq = lbqtest
correlate(partial=prsd, print=print) residual fobs lobs resid2 
dis 'Durbin-Watson Statistic:' @30 #.#### %durbin
dis
compute lbqstat = 0.0
do k=lbqdof+1,lbq
  compute lbqstat = lbqstat+%nobs*(%nobs+2)*resid2(k+1)**2/(%nobs-k)
  dis 'Ljung-Box Q-statistic using ' ## k ' autocorrelations:'
  cdf chisqr lbqstat k-lbqdof
end do k
dis
*
*  LM TEST AR(k) or MA(k)
*
* First, decide on the order of the test.
* It defaults to the seasonal frequency
if lmp
 {
if lmtest == 0
   compute lm = %cal(%year(1)+1,1) - %cal(%year(1),1)
else
   compute lm = lmtest
* Test over all intermediate values if desired
if lmloop
  do k=1,lm
    linreg(noprint) residual fobs+k lobs
    # reglist residual{1 to k}
    dis 'LM test for ' k 'th order serial correlation' 
    cdf chisqr %trsq k
  end do k
else 
  {
  linreg(noprint) residual fobs+lm lobs
  # reglist residual{1 to lm}
  dis 'LM test for ' lm 'th order serial correlation' 
  cdf chisqr %trsq lm
 }
 }
dis
*
* Simple AR(k) process tests
*
* default to seasonal frequencies
*
if artest == 0
   compute ar = %cal(%year(1)+1,1) - %cal(%year(1),1)
else
   compute ar = artest
*
* Test over intermediate values if desired
*
if arloop
 do k=1,ar
   linreg(noprint) residual fobs+k lobs
   # residual{k}
   dis 'Testing for a simple AR(' k ') order process'
   cdf ttest %beta(1)/sqrt(%xx(1,1)*%seesq) %nobs-1+k
 end do k
else
 {
  linreg(noprint) residual fobs+ar lobs
  # residual{ar}
  dis 'Testing for a simple AR(' ar ') order process'
  cdf ttest %beta(1)/sqrt(%xx(1,1)*%seesq) %nobs-1+k
  }
dis
*
* Restricted AR(1,k) test
*
if (ar .ne. 1)
 linreg(noprint) residual fobs+ar lobs
 # residual{1} residual{ar}
 exclude(noprint)
 # residual{1} residual{ar}
 dis 'Testing for a restricted AR(1 and' ar ')process'
 dis 'Test statistic =' %cdstat 'with significance' %signif
 dis
*
* Wallis Test
*
if wallis
  {
  set resnum fobs+5 lobs = (residual-residual{4})**2
  acc resnum fobs+5 lobs
  set resden fobs   lobs = residual**2
  acc resden fobs   lobs
  compute d4 = resnum(lobs)/resden(lobs)
  dis 'WALLIS Test for fourth-order serial correlation:' d4
  }
dis
*
* Non-Parametric Tests
*
compute pos = 0
compute run = 1
compute neg = 0
do p = fobs,lobs
  if (residual(p) > 0)
    compute pos = pos+1 
  if (residual(p) < 0)
    compute neg = neg+1
  if p <> fobs
     if (residual(p)*residual(p-1) < 0)
        compute run = run+1
end do p
compute zero= lobs-fobs+1-pos-neg
compute rpos = float(pos)
compute rneg = float(neg)
*
* Runs Test
*
compute zrun = (run-(2*rneg*rpos/(rneg+rpos))+0.5)/sqrt(2*rneg*rpos* $
           (2*rneg*rpos-rneg-rpos)/((rneg+rpos)**2*(rneg+rpos-1)))
*dis 'Number of: Positives =' pos 'Negatives =' neg
*dis '           Runs=      ' run '      Zeros=' zero       
dis 'Runs Test for Randomness'
cdf normal zrun 
dis;dis
*
*  ARCH(k) TEST
*
clear resid2
multiply residual residual fobs lobs resid2
if testarch == 0
  compute arch = 1
else
  compute arch = testarch
* Test over all intermediate values if desired
if looparch
  do k=1,arch
    linreg(noprint) resid2 fobs+k lobs
    # constant resid2{1 to k}
    dis 'Engle(1981) test for ' k 'th order ARCH' 
    cdf chisqr %nobs*%rsquared k
  end do k
else 
  {
  linreg(noprint) resid2 fobs+arch lobs
  # constant resid2{1 to arch}
  dis 'Engle(1981) test for ' arch 'th order ARCH' 
  cdf chisqr %nobs*%rsquared arch
  }
dis
*
* Breusch-Pagan (Koenker actually)
*
if bphet
  {
 linreg(noprint) resid2 fobs lobs
 # reglist 
 dis 'Modified Breusch-Pagan test for conditional heteroscedasticity'
 dis ' using only the original variables:' 
 cdf chisqr %nobs*%rsquared nregs-1
 scratch(matrix=newspace) (nregs-1)  fobs lobs  base
 do k=2,nregs
    multiply reglist(k) reglist(k)  fobs lobs  base+k-1
 end do k
 linreg(noprint) resid2 fobs lobs
 # reglist base+1 to base+nregs-1
 dis ' using the original variables and their squares:' 
 cdf chisqr %nobs*%rsquared 2*(nregs-1)
  }
dis;dis
*
*  RATS Statistics with higher option
*
stat residual fobs lobs
*
* Sign Test
*
compute zsign = (2*pos-(pos+neg)-1)/sqrt(pos+neg)
*dis 'Number of usable observations:' lobs-fobs+1-zero
dis 'Sign Test'
cdf normal zsign
dis
*
* Jarque-Bera test
*
dimension residmom(4)
do k=2,4
  set resid2 fobs lobs = residual**k
  acc resid2 fobs lobs
  compute residmom(k) = resid2(lobs)/%nobs
end do k
compute chistat = (%nobs/6.0)*((residmom(3)/(sqrt(residmom(2)**(3))))**2) + $
              (%nobs/24.0)*((residmom(4)/(residmom(2)**2) - 3)**2)
dis 'Jarque-Bera Test for normality:'
cdf chisqr chistat 2
dis;dis
*
*  RESET Test
*
if reset
  {
  enter(varying) rsetlist
  set pfxsq  fobs lobs = [series]rsetlist(2)**2
  set pfxcub fobs lobs = [series]rsetlist(2)**3
  set pfxqua fobs lobs = [series]rsetlist(2)**4
  dis 'Ramsey RESET test using the following powers of fitted values:'
  cmoment fobs lobs
  # rsetlist(1) reglist pfxsq pfxcub pfxqua
  linreg(cmom,noprint) rsetlist(1) fobs lobs
  # pfxsq reglist
  exclude(noprint)
  # pfxsq 
  dis 'Powers = 2, test statistic = ' %cdstat ' with significance ' %signif
  linreg(cmom,noprint) rsetlist(1) fobs lobs
  # pfxsq pfxcub reglist
  exclude(noprint)
  # pfxsq pfxcub 
  dis 'Powers=2,3, test statistic = ' %cdstat ' with significance ' %signif
  linreg(cmom,noprint) rsetlist(1) fobs lobs
  # pfxsq pfxcub pfxqua reglist
  exclude(noprint)
  # pfxsq pfxcub pfxqua
  dis 'Powers 2-4, test statistic = ' %cdstat ' with significance ' %signif
  }
dis;dis 
*
release newspace
end proc
env echo

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