*!version 1.0.0 5Feb2011 *! Pesaran (2004) CD test * Bugs: * * For feedback please email me at markus.eberhardt@economics.ox.ac.uk * Visit https://sites.google.com/site/medevecon/ for macro panel data and other Stata routines capture program drop xtcd program define xtcd, rclass prop(xt) version 10 syntax varlist(max=6 numeric) [if] [in] [, OFF RESID] preserve quietly{ qui tsset local ivar "`r(panelvar)'" local tvar "`r(timevar)'" marksample touse /* Tokenize varlist */ tokenize `varlist' * local ind `varlist' local ind "`*'" local dep : word count `varlist' if `dep'>9{ di as error "A maximum of 9 variable series can be tested at any one point." exit } * local ind "`r(varlist)'" /* Create group variable */ tempvar g egen `g' = group(`ivar') if `touse' sum `g' if `touse' local ng = r(max) /* Modifying the data set to get a column of residuals for each cross-section */ drop if missing(`g') qui keep `ind' `g' `tvar' qui reshape wide `ind', i(`tvar') j(`g') /* Creating the covariance matrix */ tempname E ABS Nobs COR forvalues m=1/`dep'{ tokenize `varlist' local name : word `m' of `varlist' tempname `E'`name' `ABS'`name' `Nobs'`name' `COR'`name' mat `Nobs'`name' = J(`ng',`ng',1) mat `E'`name' = J(`ng',`ng',1) mat `ABS'`name' = J(`ng',`ng',1) mat `COR'`name' = J(`ng',`ng',1) } * whilst just testing keep this! * mat `Nobs' = J(`ng',`ng',1) * mat `E' = J(`ng',`ng',1) * mat `ABS' = J(`ng',`ng',1) * mat `COR' = J(`ng',`ng',1) forvalues i = 1/`ng' { forvalues j = 1/`ng' { forvalues m = 1/`dep'{ local ind : word `m' of `varlist' if "`resid'" != "" { tempvar `ind'`i'M `ind'`j'N `ind'`i'M `ind'`j'U egen `ind'`i'M=mean(`ind'`i') if !missing(`ind'`i') & !missing(`ind'`j') gen `ind'`i'U=`ind'`i'-`ind'`i'M if !missing(`ind'`i'M) if `i'==`j'{ qui cap corr `ind'`i'U `ind'`i'U drop `ind'`i'U `ind'`i'M } else{ egen `ind'`j'M=mean(`ind'`j') if !missing(`ind'`i') & !missing(`ind'`j') gen `ind'`j'U=`ind'`j'-`ind'`j'M if !missing(`ind'`j'M) qui cap corr `ind'`i'U `ind'`j'U if _rc==2000 | `r(N)'==2 { di " " di in red "Error: The panel is highly unbalanced." di in red "Not enough common observations across panel to perform Pesaran's test." error 2001 } drop `ind'`i'U `ind'`j'U `ind'`i'M `ind'`j'M } } if "`resid'" == "" { qui cap corr `ind'`i' `ind'`j' if _rc==2000 | `r(N)'==2 { di " " di in red "Error: The panel is highly unbalanced." di in red "Not enough common observations across panel to perform Pesaran's test." error 2001 } } local name : word `m' of `varlist' mat `E'`name'[`i',`j'] = `r(rho)'*sqrt(`r(N)') mat `Nobs'`name'[`i',`j'] = `r(N)' mat `ABS'`name'[`i',`j'] = abs(`r(rho)') mat `COR'`name'[`i',`j'] = `r(rho)' } * end of variable loop } * end of j loop } * end of i loop /* Creating a 1x1 ``matrix'' with the sum of the matrix E (including element by element multiplication by T_{ij}) */ tempname A B C D F forvalues m = 1/`dep'{ local name : word `m' of `varlist' tempname `A'`name' `B'`name' `C'`name' `D'`name' `F'`name' mat `A'`name' = J(colsof(`E'`name'),1,1) mat `B'`name' = `A'`name''*`E'`name'*`A'`name' mata: `C'`name' = st_matrix("`Nobs'`name'") mata: `C'`name' = vec(`C'`name') mata: `C'`name' = colsum(`C'`name') mata: st_matrix("`C'`name'", `C'`name') mat `D'`name' = `A'`name''*`ABS'`name'*`A'`name' mat `F'`name' = `A'`name''*`COR'`name'*`A'`name' } /* Compute Test */ tempname pesaranM pesaranabsM vmM absvmM avg_obsM numb_coeffM n_obsM mat `pesaranM' = J(`dep',1,0) mat `pesaranabsM' = J(`dep',1,0) mat `vmM' = J(`dep',1,0) mat `absvmM' = J(`dep',1,0) mat `avg_obsM' = J(`dep',1,0) mat `numb_coeffM' = J(`dep',1,0) mat `n_obsM' = J(`dep',1,0) * tempname pesaran pesaranabs v vm absv absvm nobs avg_obs corr_coeff forvalues m = 1/`dep'{ local name : word `m' of `varlist' * tempname `pesaran'`name' `pesaranabs'`name' `v'`name' `vm'`name' `absv'`name' `absvm'`name' `nobs'`name' `avg_obs'`name' `corr_coeff'`name' local pesaran = sqrt( 2/(`ng'*(`ng'-1))) *(`B'`name'[1,1]-trace(`E'`name'))/2 local pesaranabs = abs(`pesaran') mat `pesaranM'[`m',1] = `pesaran' mat `pesaranabsM'[`m',1]= `pesaranabs' local v = (`F'`name'[1,1]-trace(`COR'`name'))/2 local vm = `v'*2/(`ng'*(`ng'-1)) local absv = (`D'`name'[1,1]-trace(`ABS'`name'))/2 local absvm = `absv'*2/(`ng'*(`ng'-1)) mat `vmM'[`m',1] = `vm' mat `absvmM'[`m',1]= `absvm' local nobs = `C'`name'[1,1] local avg_obs = `nobs'/(`ng'*(`ng'-1)) local corr_coeff = `ng'*(`ng'-1) mat `avg_obsM'[`m',1] = `avg_obs' mat `numb_coeffM'[`m',1] = `corr_coeff' mat `n_obsM'[`m',1]= `nobs' } restore } * end of quietly di "" di "" di in gr _col(2) "Average correlation coefficients & Pesaran (2004) CD test" di "" if ("`resid'")!=""{ di in gr _col(2) "Residual series tested: " in ye _col(20) "`varlist'" local var_or_res = "variables" } else { di in gr _col(2) "Variables series tested: " in ye _col(20) "`varlist'" local var_or_res = "residuals" } di in gr _col(32) "Group variable: " in ye _col(47) "`ivar'" di in gr _col(30) "Number of groups: " in ye _col(47) "`ng'" di in gr _col(21) "Average # of observations: " in ye _col(47) %-4.2f `avg_obsM'[1,1] if `avg_obsM'[1,1]!= round(`avg_obsM'[1,1]){ di in gr _col(38) "Panel is: " in ye _col(47) "unbalanced" } else di in gr _col(38) "Panel is: " in ye _col(47) "balanced" di "" di as text "{hline 13}{c TT}{hline 43}" di as text _col(2) " Variable" " {c |}" _col(19) "CD-test" _col(28) "p-value" _col(40) "corr" _col(46) "abs(corr)" di as text "{hline 13}{c +}{hline 43}" forvalues m=1/`dep'{ local name : word `m' of `varlist' di as text %12s abbrev("`name'",12) " {c |}" as result _col(19) %7.2f `pesaranM'[`m',1] _continue di as result _col(28) %7.3f 2*(1-normal(`pesaranabsM'[`m',1])) _col(39) %5.3f `vmM'[`m',1] _continue di as result _col(48) %5.3f `absvmM'[`m',1] if (`m' < `dep') { di as text "{hline 13}{c +}{hline 43}" } else { di as text "{hline 13}{c BT}{hline 43}" } } di in gr _col(2) "Notes: Under the null hypothesis of cross-section " di in gr _col(9) "independence CD ~ N(0,1)" return matrix avg_obs = `avg_obsM' return matrix numb_coeff = `numb_coeffM' return scalar N_g = `ng' return matrix pesaran = `pesaranM' return matrix avgcorr = `vmM' return matrix abscorr = `absvmM' return matrix nobs = `n_obsM' return local variables `var_or_res' return local varname `varlist' end