*! didparallel 1.0.0 2026/04/16 GuanpengYan
prog def didparallel, eclass
	version 16
    qui xtset
    if "`r(panelvar)'" == "" | "`r(timevar)'" == "" {
		di as err "panel variable or time variable missing, please use -{bf:xtset} {it:panelvar} {it:timevar}"
		exit 198
    }
	syntax anything, TREATVar(varname) [BASEperiod(integer -1) range(numlist min=2 max=2 integer missingokay) frame(string) noFIGure SAVEGraph(string) noOmit]
	loc panelvar "`r(panelvar)'"
    loc timevar "`r(timevar)'"
	local graphlist = ""
	if "`range'" ==  "" {
		loc range ". ."
	}
**# Check estimation
	cap qui estimates restore `anything'
	if _rc {
		di as err "{bf:`anything'} should be an estimation generated by {bf:estimates store}."
		exit 198
	}
	else {
		qui estimates restore `anything'
		loc estimatename "`anything'"
		loc cmd "`e(cmd)'"
		loc cmdline "`e(cmdline)'"
	}
**# Check treatvar()
	cap confirm numeric var `treatvar'
	if _rc {
		di as err "{bf:`treatvar'} should be a numeric variable in dataset"
		exit 198
	}
**# Check frame()
	if "`frame'" == "" tempname frame
	else {
		cap frame drop `frame'
		qui pwf
		if "`frame'" == "`r(currentframe)'" {
			di as err "invalid frame() -- current frame can not be specified"
			exit 198
		}
		loc framename "`frame'"
	}
	qui frame create `frame'
	mata: data = st_data(., "`panelvar' `timevar' `treatvar'");
	preserve
	mata: didparallel(data, "`panelvar'", "`timevar'", "`treatvar'", "`cmdline'", strtoreal(tokens("`range'")), "`frame'", `baseperiod', ("`omit'"!= "" ? 0 : 1))
	restore
	frame `frame'{
		twoway  ///
		(rcap ul ll time) ///
		(connected b time, msymbol(O)) ///
		, xlabel(`xlabel', nogrid)  ylabel(, nogrid) xline(`xline', lp(dot)) ///
		yline(0, lp(dot)) xtitle("number of periods since the treatment onset") ytitle("dynamic treatment effects") ///
		legend(order(2 "Point Estimate" 1 "95% Confidence Interval") position(6) rows(1)) nodraw name(parallel, replace)
		local graphlist = "`graphlist' parallel"
	}
	cap local graphlist = strltrim("`graphlist'")
**# Display and save graphs
	if "`figure'" != "nofigure" {
	    if "`savegraph'" != "" {
			di
			ereturn local graphlist "`graphlist'"
			didparallel_SaveGraph `savegraph'
		}
		else foreach graph in `graphlist'{
			capture graph display `graph'
		}
    }
	ereturn loc frame "`framename'"
	cap ereturn loc graph "`graphlist'"
end

program didparallel_SaveGraph
	version 16
	preserve
	syntax [anything], [asis replace]
	foreach graph in `e(graphlist)'{
		graph save `graph' `anything'_`graph', `asis' `replace'
	}
end
* Version history
* 1.0.0 Submit the initial version