*! version 1.0.0 13Jul2020 //----------------------------------------------------------------------------- // // mivcausal - Testing the hypothesis about the signs of the 2SLS weights // Test by Romano, Shaikh and Wolf (2014) // //----------------------------------------------------------------------------- capt program drop mivrsw mivrsw_firststep //----------------------------------- // Main function for the RSW test //----------------------------------- program mivrsw, rclass version 10.0 syntax anything [if] [in] [, SEEd(integer 1) /// PRECision(integer 2) /// BOOTstrap(integer 1000) /// VAROPTion(string) /// CLuster(varlist)] // Step 1 - Compute the test statistics (from Mintest) scalar That_rsw = max(-t_mint[1, 1], -t_mint[1, 2]) // Step 2 - First-step bootstrap * Initialize the matrices mat mu_rsw = J(`bootstrap', 2, 0) mat bsfirst = J(`bootstrap', 3, 0) * Conduct the bootstrap using the function `mivrsw_firststep' forval b = 1/`bootstrap' { * Bootstrap and regression local b_seed = `b' + `seed' - 1 qui mivrsw_firststep `anything', varopt(`varoption') seed(`b_seed') /// cl(`cluster') * Obtain the bootstrap estimators forval k = 1/2 { mat mu_rsw[`b', `k'] = r(bs`k') mat bsfirst[`b', `k'] = /// sqrt(NN) * (mu_rsw[`b', `k'] + /// thetaols[1, `k']) / thetasys[1, `k'] } mat bsfirst[`b', 3] = max(bsfirst[`b', 1], bsfirst[`b', 2]) } // Step 3 - Second-step bootstrap * Initialize the matrices scalar pchange = 0.1^(`precision') scalar pv = -pchange scalar rswdecision = 0 * Initiate the for-loop to get the p-value while ((rswdecision == 0) & (pv <= 1)) { * Update the candidate p-value scalar pv = pv + pchange * Compute the required percentile preserve clear * Generate data from matrix qui svmat bsfirst * Compute quantile local beta = 100 * (1 - pv * .1) if `beta' == 100 { qui sum bsfirst3 scalar rquan = r(max) } else if `beta' == 0 { qui sum bsfirst3 scalar rquan = r(min) } else { qui _pctile bsfirst3, p(`beta') scalar rquan = r(r1) } restore * Compute r-star mat rstar = J(1, 2, 0) forval i = 1/2 { mat rstar[1, `i'] = /// -thetaols[1, `i'] + thetasys[1, `i'] * rquan / sqrt(NN) } * Determine whether the second-step is required if (rstar[1, 1] <= 0 & rstar[1, 2] <= 0) { scalar rswdecision = 0 } else { * Initialize the matrices mat bssecond = J(`bootstrap', 3, 0) mat lambdastar = J(1, 2, 0) * Compute lambda-star forval i = 1/2 { mat lambdastar[1, `i'] = min(0, rstar[1, `i']) } preserve clear * Make the variables from matrix qui svmat bsfirst * Make the new variables forval i = 1/2 { qui gen bssecond`i' = /// sqrt(NN) * lambdastar[1, `i'] / thetasys[1, `i'] - /// bsfirst`i' } * Gen the maximum of the two qui gen bssecond3 = max(bssecond1, bssecond2) * Save the matrix qui mkmat bssecond3, matrix(bssecond3) restore * Compute the required percentile and the critical value preserve clear * Make the variables from matrix qui svmat bssecond3 * Compute quantile local secondstep = 100 * (1 - pv + .1 * pv) if `secondstep' == 100 { qui sum bssecond3 scalar cv_rsw = r(max) } else if `secondstep' == 0 { qui sum bssecond3 scalar cv_rsw = r(min) } else { qui _pctile bssecond3, p(`secondstep') scalar cv_rsw = r(r1) } restore * Update the decision if That_rsw > cv_rsw { scalar rswdecision = 1 } } } // Step 4 - Return the p-value return scalar pval_rsw = pv end //----------------------------------- // Function for the first-step bootstrap in the RSW test //----------------------------------- program mivrsw_firststep, rclass version 10.0 syntax anything [, VAROPTion(string) /// SEEd(integer 1) /// CLuster(varlist)] // Step 1 - Retrieve the treatment, instruments and covariates * Treatment local dvar: word 1 of `anything' * Instruments local zvars "" forval i = 2/3 { local ztemp: word `i' of `anything' local zvars `zvars' `ztemp' } * Covariates local vardrop `dvar' `zvars' local xvars: list anything - vardrop // Step 2 - Bootstrapping procedure preserve * Set seed and bootstrap set seed `seed' qui bsample NN // Step 3 - Regress Z on D and X * Initialize vector to store the coefficients and standard errors scalar j = 1 * Regress Z_{j} on D and X foreach z of local zvars { if "`varoption'" == "unadjusted" { qui reg `dvar' `z' `xvars' } else if "`varoption'" == "robust" { qui reg `dvar' `z' `xvars', `varoption' } else if "`varoption'" == "cluster" { qui reg `dvar' `z' `xvars', cluster(`cluster') } * Store the coefficients qui mat rtab_rsw = r(table) return scalar bs`=j' = -rtab_rsw[1,1] scalar j = j + 1 } restore end