Modified Jones Model
//Get signed and unsigned total accruals
gen t_accruals=ib-oancf //Accruals are not scaled at this point
rename t_accruals raw_ta
gen uta=abs(raw_ta)
label var uta "unsigned total accruals"
//Calculate discretionary accruals
use "F....\accruals.dta",clear
drop consol popsrc datafmt stbo costat
drop if at==.
destring gvkey,replace
duplicates drop gvkey fyear,force
xtset gvkey fyear
gen year=fyear if fyr>5
replace year=fyear+1 if fyr<6
//dlc is short term debt; lct is current liabilities; act is current assets; ch is cash; rect is receivables
foreach x of varlist act dlc lct sale rect ch{
gen d_`x' = `x'- L.`x'
}
gen l_at=L.at
//gen ta= (d_act + d_dlc - d_lct - d_ch - dp)/l_at //If you need to calculate accruals from balance sheet
gen ta=raw_ta/l_at
gen l_sale_def=(d_sale+d_rec)/l_at
//gen l_sale=d_sale/l_at //Alternative way of calculating scaled sales
gen l_ppe=ppe/l_at
gen roa=ib/at
foreach x in ta l_sale l_ppe roa{
drop if missing(`x')
}
replace sic=substr(sic,1,2)
bys sic fyear: gen num=_N
drop if num<20
drop num
winsor2 ta l_sale l_ppe roa, replace cuts(1 99) by(sic year)
bys sic fyear:asreg ta l_sale l_ppe roa, minimum(20) save(dis_accruals)
drop if missing(ta)
gen da= ta-(_b_cons+_b_l_sale*l_sale+_b_l_ppe*l_ppe+roa*_b_roa)
keep gvkey da year sic
destring sic,replace
//winsor2 da,replace cuts(1 99) //You can decide which step to do winsorize
duplicates drop gvkey year,force
save dis_accruals.dta,replace
DD 2002 Model, cash flow based
//oancf = cash flow from operations
insheet using "...accruals_dd.csv",clear
gen year=substr(datadate,1,4)
drop if oancf=="NA"
foreach x in recch invch apalch txach aoloch{
replace `x'="0" if `x'=="NA"
}
destring at year fyr oancf recch invch apalch txach aoloch, force replace
gen fyear=year if fyr>5
replace fyear=year-1 if fyr<6
drop v1 datadate
gen d_wc=recch+invch+aoloch-apalch-txach
keep gvkey year fyear d_wc at oancf
duplicates drop gvkey fyear,force
merge 1:1 gvkey fyear using accruals_sic.dta
keep if _merge==3
drop _merge
replace sic=substr(sic,1,2)
xtset gvkey fyear
rename oancf cfo
gen cfo_l1=L.cfo
gen cfo_f1=F.cfo
foreach x in d_wc cfo cfo_l1 cfo_f1{
replace `x'=`x'/at
drop if missing(`x')
}
winsor2 d_wc cfo cfo_l1 cfo_f1,replace cuts(1 99)
bys sic fyear:asreg d_wc cfo cfo_l1 cfo_f1, minimum(20)
drop if _Nobs==.
gen res=d_wc-_b_cfo*cfo-_b_cfo_l1*cfo_l1-_b_cfo_f1*cfo_f1-_b_cons
//DD model: accrual quality is sd of the residual
rangestat (sd) res, interval(fyear -4 0) by(gvkey)
keep gvkey year res_sd
rename res_sd da
duplicates drop gvkey year,force
save dd_accruals.dta,replace