*
* @ARCHTest(options)  series  start end
*
* Computes tests for ARCH effects by regressing squares of an input series (which
* will usually be residuals) on constant and lags of the squares and testing the
* lags.
*
* Parameters:
*   series      series to test
*   start end   range of series to use. By default the defined range of series
*
* Options:
*   LAGS=(maximum) number of lags [4]
*   SPAN=spacing between number of lags in a test sequence. SPAN=1 will give a table
*        of tests for all lags from 1 to the LAG option. The default is to test only
*        the value of the LAGS option.
*   DFC=degrees of freedom correction for tests. By default, 0. If <<series>> are
*       residuals from an ARCH or GARCH, DFC should be the number of ARCH/GARCH
*       parameters.
*   FORM=[F]/LM determines whether F-test or Lagrange multiplier form is used
*   [PRINT]/NOPRINT
*
* Variables Defined:
*   %CDSTAT   F-statistic for test with LAG option lags
*   %SIGNIF   Significance level of %CDSTAT
*
* Revision Schedule:
*   04/2008 Written by Tom Doan, Estima
*
procedure archtest series start end
type series         series
type integrer       start end
*
option integer      lags    4
option integer      dfc     0
option integer      span    0
option choice       form    1  f  lm
option switch       print   1
*
local series        ressqr
local integer       startl endl spanl lagnum num jj
*
* Get the working value for the span. If it's zero (or out-of-range), make it
* equal to <<lags>> so we'll just do the one test.
*
if span<=0.or.span>lags
   compute spanl = lags
else
   compute spanl = span
*
* Figure out the range of the series to use
*
inquire(series=series)  startl<<start  endl<<end
*
set ressqr startl endl = series**2
*
if print {
   report(action=define)
   report(atrow=1,atcol=1,span) "F-test of no ARCH vs. ARCH in "+%label(series)
   report(atrow=2,atcol=1,span) "Using data from "+%datelabel(startl)+" to "+%datelabel(endl)
   report(atrow=4,atcol=1) "Lags" "Statistic" "Signif. Level"
}
*
* If the user gave a LAGS which isn't a multiple of SPAN, do all multiples of SPAN
* less than LAGS, and then LAGS at the end.
*
compute lagnum = 0
while lagnum<lags {
   compute lagnum = lagnum + spanl
   if lagnum>lags
      compute lagnum=lags
   linreg(noprint,dfc=dfc) ressqr startl+lagnum endl
   # constant ressqr{1 to lagnum}
   if form==1 {
      exclude(noprint)
      # ressqr{1 to lagnum}
   }
   else
      cdf(noprint) chisqr %trsquared lagnum
   if print
      report(row=new,atcol=1) lagnum %cdstat %signif
}
if print {
   report(action=format,atcol=2,tocol=2,picture="*.###")
   report(action=format,atcol=3,tocol=3,picture="*.#####")
   report(action=show)
}
end


