************************************************************************
*                                                                      *
*       RATS CODE FOR MULTIVARIATE GROUP MEAN PANEL FMOLS TESTS        *
*                     IN HETEROGENEOUS PANELS                          *
*                                                                      *
*   Author: Peter Pedroni, Indiana University, ppedroni@indiana.edu    *
*                                                                      *
*                            REFERENCES:                               *
*                                                                      *
*   For Theory and Monte Carlos:                                       *
*                                                                      *
*   Pedroni, Peter (1996) "Fully Modified OLS for Heterogeneous        *
*   Cointegrated Panels and the Case of Purchasing Power Parity,"      *
*   Indiana University Working Papers in Economics, No. 96-020.        *
*                                                                      *
*   Pedroni, Peter (2000) "Fully Modified OLS for Heterogeneous        *
*   Cointegrated Panels," Advances in Econometrics, Vol. 15, 93-130,   *
*   NONSTATIONARY PANELS, PANEL COINTEGRATION AND DYNAMIC PANELS,      *
*   JAI Press.                                                         *
*                                                                      *
*   For general discussion and application:                            *
*                                                                      *
*   Pedroni, Peter (2001) "Purchasing Power Parity Tests in            *
*   Cointegrated Panels," Review of Economics and Statistics, 83,      *
*   727-731, November, 2001.                                           *
*                                                                      *
*   version: group-fm.prg   - modified for small sample adjustments    *
*    computes panel group mean estimator from Pedroni (1996, 2000)     *
*                                                                      *
************************************************************************
environment noecho


                ***  USER INPUT SECTION ***

compute Tperiods = 100       ;* time series dimension, T
compute Nsecs = 20           ;* cross section dimension, N
compute mlag = 3             ;* lag truncation for kernel estimator
compute Tdum = 0             ;* set to 1 to subtract time means, else 0
compute m = 3                ;* number of regressors
allocate 0 Nsecs*Tperiods    ;* set allocate to at least N*T

dec vec bvec(m)
compute bvec = || 1.0, 1.0, 1.0||  ;* null values for slope vector

open data dataset.wks        ;* read stacked panel data from file
data(org=obs,format=wks)     ;* one column of length N*T per variable
                             ;* stacked as i=1,t=1...T; i=2,t=1...T, etc.
dec vec[series] datavec(m+1)
set datavec(1) = var1        ;* name of LHS variable in data
set datavec(2) = var2        ;* name of first RHS var in data
set datavec(3) = var3        ;* name of second RHS var in data
set datavec(4) = var4        ;* name of third RHS var in data, etc.

dec vec[label] labelvec(m+1)
compute labelvec(1) = 'y'    ;* desired label for LHS variable
compute labelvec(2) = 'x1'   ;* desired label for first RHS variable
compute labelvec(3) = 'x2'   ;* desired label for second RHS variable
compute labelvec(4) = 'x3'   ;* desired label for third RHS variable, etc.

* Note: You may also need to adjust the section of code which displays
*       results, at the bottom of this program, depending on the number
*	of RHS variables that you have.
*	
*	Individual FMOLS estimates will only be displayed when you do not
*	use the TDUM option.
*************************************************************************
   * (do not change anything below this line for standard run) *


	                *** MAIN SOURCE CODE ***

display ' '
display '      Currently computing panel statistics. Please wait. '
display ' '

dec vec[real] temp(m) tden(m) iFMOLS(m) iFMtstat(m) itemp1(m) $
              pfg(m) pfgt(m) O21(m) G21(m) G12(m) V21(m)
dec rect[real] gammastar(1,m) gXX(m,m) ytemp(1,1) $
              O22(m,m) G22(m,m) V22(m,m)
dec vec[series] xvec(m) dxvec(m) indfm(m) indfmt(m) dvec(m+1) rvec(m+1) $
               g21ser(m) g12ser(m)
dec rect[rect] G(2,2)
dec rect[series] g22ser(m,m)
dec vec W

if tdum == 1
{
calander(panelobs=Tperiods)
do K=1,m+1
  panel datavec(K) / datavec(K) * entry 1.0 indiv 0.0 time -1.0
end do K
calander
}
end if

ewise pfg(i) = 0.0
ewise pfgt(i) = 0.0

do J=1,Nsecs

  do K=1,M+1
    set dvec(K) 1 Tperiods = datavec(K)(T+(J-1)*Tperiods)
    diff dvec(K) 2 Tperiods rvec(K)
    diff(center) rvec(K) 2 Tperiods rvec(K)
  end do K

  do K=1,M
    set xvec(K) 1 Tperiods = dvec(K+1)
    set dxvec(K) 2 Tperiods = rvec(K+1)
  end do K

   linreg(noprint) dvec(1) 2 Tperiods ehat
      # dvec(2) to dvec(m+1) constant

set rvec(1) =  ehat

compute maxlag = mlag
VCV(matrix=V,noprint) 2 Tperiods
  # rvec(1) to rvec(m+1)
mcov(damp=1.0,lags=maxlag,noprint) 2 Tperiods
  # rvec(1) to rvec(m+1)

compute O11 = (1.0/(Tperiods-1.0))*%CMOM(1,1)
do q=1,m
compute O21(q)= (1.0/(Tperiods-1.0))*%CMOM(q+1,1)
compute V21(q)= V(q+1,1)
do r=1,m
compute O22(q,r) = (1.0/(Tperiods-1.0))*%CMOM(q+1,r+1)
compute V22(q,r) = V(q+1,r+1)
end do q; end do r

compute maxlag = mlag
dimension W(maxlag)
do I=1,maxlag
compute W(I) = 1.0 - I/(maxlag+1.0)
end do I

cross(covariances,noprint) rvec(1) rvec(1) 2 Tperiods 1 maxlag $
	g11ser
do q=1,m
cross(covariances,noprint) rvec(q+1) rvec(1) 2 Tperiods 1 maxlag $
	g21ser(q)
cross(covariances,noprint) rvec(1) rvec(q+1) 2 Tperiods 1 maxlag $
	g12ser(q)
do r=1,m
cross(covariances,noprint) rvec(q+1) rvec(r+1) 2 Tperiods 1 maxlag $
	g22ser(q,r)
end do q ; end do r

make g11vec 1 maxlag maxlag
# g11ser
compute G(1,1) = %scalar(tr(W)*g11vec)
do q=1,m
make g21vec 1 maxlag maxlag
# g21ser(q)
compute G21(q) = %scalar(tr(W)*g21vec)
make g12vec 1 maxlag maxlag
# g12ser(q)
compute G12(q) = %scalar(tr(W)*g12vec)
do r=1,m
make g22vec 1 maxlag maxlag
# g22ser(q,r)
compute G22(q,r) = %scalar(tr(W)*g22vec)
end do q ; end do r

do s=2,Tperiods
   ewise temp(I) = dxvec(I)(s)
   compute ytemp = tr(o21)*inv(o22)*temp
   set ystar s s = dvec(1) - ytemp(1,1)
end do s

compute term1 = tr(G12+V21)
compute term2 = tr(o21)*inv(o22)*(G22+V22)
compute gammastar = term1 - term2

linreg(noprint) ystar 2 Tperiods
# xvec(1) to xvec(m) constant

ewise gXX(I,J) = %XX(I,J)
ewise itemp1(I) = %beta(I)
compute itemp2 = (Tperiods-1.0)*gammastar*gXX
compute iFMOLS = itemp1 - tr(itemp2)
ewise tden(I) = sqrt(%XX(I,I)*o11)
ewise iFMtstat(I) = (iFMOLS(I)-bvec(I))/tden(I)

do k=1,m
  set indfm(k) J J = iFMOLS(k)
  set indfmt(k) J J = iFMtstat(k)
end do k

compute pfg = pfg + iFMOLS
compute pfgt = pfgt + iFMtstat

end do J

compute pfg = (1.0/Nsecs)*pfg
compute pfgt = (1.0/sqrt(Nsecs))*pfgt


***********************************************************************

                *** DISPLAY INDIVIDUAL AND PANEL RESULTS ***

display ' '
display 'dependent variable :' labelvec(1)

display ' '
if tdum == 0 ; { ; display 'common time dummies NOT included' ; }
if tdum == 1 ; { ; display 'common time dummies included' ; }
display ' '
display 'null vector for t-stats is ' ; write bvec
display ' '
display ' '
display '            INDIVIDUAL FMOLS RESULTS'
display '            (t-stats in parentheses)'
display ' '
display '************************************************'

display ' '
if tdum == 0
{
display ' '
display  @5 labelvec(1) @15 labelvec(2) @26 labelvec(3) @40 'panel member'
display ' '

do i=1,Nsecs
 display @6 ##.## indfm(1)(i) @+6 ##.## indfm(2)(i) $
         @+6 ##.## indfm(3)(i) @+5 I
 display @4 '(' ##.## indfmt(1)(i) ')' $
         @+2 '(' ##.## indfmt(2)(i) ')' $
         @+2 '(' ##.## indfmt(3)(i) ')'
 display ' '

}
end do i
}
display ' '
display ' ************************************************ '
display ' '

display '       PANEL GROUP FMOLS RESULTS    '
display '        (t-stats in parentheses)'
display ' '

 display @6 ##.## pfg(1) @+6 ##.## pfg(2) $
         @+6 ##.## pfg(3)
 display @4 '(' ##.## pfgt(1) ')' $
         @+2 '(' ##.## pfgt(2) ')' $
         @+2 '(' ##.## pfgt(3) ')'

display ' '
display ' '
display '      N =' Nsecs ', T =' Tperiods  ', max-lag =' mlag
display ' '
display ' ************************************************ '

end; end program