I write a loop of cross-sectional regressions for calculating abnormal accruals. This program can be easily modified and replaced with Jones, modified Jones, or Dechow and Dichev model.
I add detailed comments in the program to help you prepare the input file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
set more off cd "D:\Dropbox" use funda_full_regdata, clear //This is the input file. Download required Compustat data and then //compute all dependent variable and independent variable (e.g., total //accruals scaled by total assets (ta), delta sales scaled by total //asset (dsale), PP&E scaled by total assets (ppe). keep if fyear>=2003 & fyear<=2014 * Remove obs without required data foreach v in ta dsale ppe { drop if `v'==. } * Handle outliers for each industry year ge trunc=0 local vlist "ta dsale ppe" egen groupid=group(fyear sic2) sum groupid, meanonly local num=r(max) forvalues i=1/`num' { foreach v in `vlist' { _pctile `v' if groupid==`i', p(1 99) replace trunc=1 if groupid==`i' & (`v'<r(r1) | `v'>r(r2)) //drop top and bottom 1%. You can do winsorize as well } } drop if trunc==1 drop trunc groupid * Require at least 20 obs for each estimation bysort groupid: egen obsnum=count(datadate) keep if obsnum>=20 drop groupid egen groupid=group(fyear sic2) sum groupid, meanonly local num=r(max) * Run cross-sectional regressions ge da=. ge regobs=. ge df=. ge r2a=. foreach x in dsale ppe _cons { ge `x'_b=. ge `x'_se=. } forvalues i=1/`num' { regress ta dsale ppe if groupid==`i' predict resid if groupid==`i', residual replace da=resid if groupid==`i' drop resid replace regobs=e(N) if groupid==`i' replace df=e(df_r) if groupid==`i' replace r2a=e(r2_a) if groupid==`i' foreach x in dsale _cons { replace `x'_b=_b[`x'] if groupid==`i' replace `x'_se=_se[`x'] if groupid==`i' } } save da, replace //This is the output file. It includes: //DA - discretionary accruals (residuals) //Regression coefficients such as dsale_b, ppe_b //Standard error for each coefficient such as dsale_se, ppe_se //Some regression stats such as number of obs (regobs), (degree of //freedom (df), and adjusted R squared (r2a) |
I am using your codes to calculate DA. However, I get ” Invalid Syntax”. Can you please help me figure out what I do wrong.
this the codes I used;
forvalues i=1/
num' {
i’regress ta x1 x2 x3 x4 x5 if groupid==
predict resid if groupid==
i', residuals
i’replace da=resid if groupid==
drop resid
replace regobs=e(N) if groupid==
i'
i’replace df=e(df_r) if groupid==
replace r2a=e(r2_a) if groupid==
i'
x’_b=_b[foreach x in x1 x2 x3 x4 x5 _cons {
replace
x'] if groupid==
i’replace
x'_se=_se[
x’] if groupid==`i’}
}
Your codes look good to me. If you can send me the entire codes, I may be able to pinpoint the error.
those are the entire codes I used:
* Remove obs without required data
foreach v in ta x1 x2 x3 x4 x5 {
drop if
v'==.
}
* Handle outliers for each industry year
ge trunc=0
local vlist "ta x1 x2 x3 x4 x5"
egen groupid=group(fyear sic_2)
sum groupid, meanonly
local num=r(max)
forvalues i=1/num’ {
foreach v in
vlist' {
v’ if groupid==_pctile
i', p(1 99)
i’ & (replace trunc=1 if groupid==
v'r(r2)) //drop top and bottom 1%. You can do winsorize as well
}
}
drop if trunc==1
drop trunc groupid
* Require at least 20 obs for each estimation
bysort groupid: egen obsnum=count(fyear)
keep if obsnum>=20
drop groupid
egen groupid=group(fyear sic_2)
sum groupid, meanonly
local num=r(max)
* Run cross-sectional regressions
ge da=.
ge regobs=.
ge df=.
ge r2a=.
foreach x in x1 x2 x3 x4 x5 _cons {
ge x’_b=.
ge
x'_se=.
}
forvalues i=1/num’ {
regress ta x1 x2 x3 x4 x5 if groupid==
i'
i’, residualspredict resid if groupid==
replace da=resid if groupid==
i'
i’drop resid
replace regobs=e(N) if groupid==
replace df=e(df_r) if groupid==
i'
i’replace r2a=e(r2_a) if groupid==
foreach x in x1 x2 x3 x4 x5 _cons {
replace
x'_b=_b[
x’] if groupid==i'
x’_se=_se[replace
x']if groupid==
i’}
}
save da, replace
Note that when I run all the entire codes, I get da regobs r2a x1_b for the first regression. and then I get ” invalid syntax”.
I am working on discretionary accrual model. I am having problem with calculating the Total accrual and PPE in Stata . I used this command :gen TAC =(NI-CFO)/lagged TA and Gross property plant and equipment using the following command :gen var name =PPE/lagged TA. How do I go about it please
Do you mean you don’t know how to calculate lagged TA? If this is your problem, check the command
tsset
in Stata documentation. Stata is very powerful in calculating lagged value or changes in value.Hello Kai,
Could you please provide us with the modified jones model’s code?
Thanks a lot,
Hello Dr. Chen,
I just want to say thank for sharing the helpful codes and instructions. I just replicated Jones and Mod Jones by following your codes, and it really helps me to write it in a more efficient way.
Thank you once again.
Hui