*
* Computes a least squares regression with the covariance matrix
* proposed by Hodrick(1992) "Dividend Yields and Expected Stock Returns:
* Alternative Procedures for Inference and Measurement", Review of
* Financial Studies, vol 5, no 3, 357-386.
*
* Note that the calculation is specific to multiple step predictability
* regressions. It uses the residuals from a one-step regression to
* compute the covariance matrix for a k-step regression. The dependent
* variable on the procedure line is for the multiple-step predictability
* regression. You can provide the one step results either by giving the
* one-step dependent variable (using the ONESTEP option) or by giving
* the residuals directly (using the EPS option); you have to do one of
* those two. You also need to provide the number of steps in the
* regression that you're running by using the STEPS option.
*
* @OLSHodrick( options ) depvar start end
* # list of explanatory variables
*
* Parameters:
*   depvar    = dependent variable for multi-step predictability regression
*   start end = range to use (default is maximum allowed)
*
* Options:
*   STEPS  =number of steps for the predictability regression
*   ONESTEP=one-step-ahead analogue to the <<depvar>>
*   EPS    =one-step-ahead residuals
*   [PRINT]/NOPRINT
*
*   You must supply the STEPS option and either ONESTEP or EPS.
*
* Revision Schedule:
*   03/2011 Written by Tom Doan, Estima
*   03/2012 Add NOPRINT option
*   09/2017 Correct DO TIME loop---skipped first usable data point
*   09/2017 Add handling of embedded missing values
*
procedure OLSHodrick depvar start end
option integer steps
option series  onestep
option series  eps
option switch  print   1
*
local  symm    s0 savexx
local  vect    wk savebeta
local  series  epsw insmpl
local  integer i time rstart rend
*
if .not.%defined(steps) {
   disp "##Syntax: @OLSHodrick(STEPS=# of steps,other options)"
   return
}
if .not.%defined(eps).and..not.%defined(onestep) {
   disp "##Syntax: @OLSHodrick(EPS=series of one-step residuals or ONESTEP=one-step dependent variable)"
   return
}
*
* Do the desired regression
*
linreg(noprint) depvar start end
compute savebeta=%beta,savexx=%xx
compute rstart=%regstart(),rend=%regend()
set insmpl rstart rend = %valid(%resids)
*
if %defined(eps)
   set epsw rstart rend = eps
else
   linreg(lastreg,noprint) onestep rstart rend epsw
*
compute s0=%zeros(%nreg,%nreg)
do time=rstart+steps-1,rend
   compute wk=%zeros(%nreg,1)
   do i=0,steps-1
      if %valid(epsw(time)).and.insmpl(time-i)
         compute wk=wk+epsw(time)*%eqnxvector(0,time-i)
   end do i
   compute s0=s0+%outerxx(wk)
end do time
*
linreg(lastreg,create,coeffs=savebeta,covmat=savexx*s0*savexx,form=chisq,$
  print=print,title="Least Squares with Hodrick standard errors") depvar
end
