mcpField
S
stata-accounting-research

stata-accounting-research

github.com/brycewang-stanford数据与数据库4.8k71 次安装2 天前更新
代码仓库

关于 stata-accounting-research

面向会计实证研究者的 STATA 方法指南,汇集财务报告、审计、税务和管理会计研究中的常见代码模式。内容涵盖数据处理、模型估计、稳健性检验及论文表格输出。

主要功能

  1. 01COMPUSTAT 数据准备
  2. 02盈余质量模型示例
  3. 03事件研究与面板回归
  4. 04倾向得分匹配和 Heckman 模型
  5. 05生成论文用表格

适用场景

  1. 01估计可操纵应计项目
  2. 02分析公告事件的短期收益
  3. 03检验监管变化或审计影响
  4. 04制作回归与描述统计表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/brycewang-stanford/auto-empirical-research-skills --skill stata-accounting-research

安装后在 Claude Code 中输入/stata-accounting-research确认已加载。

详细介绍

STATA 会计研究指南

概述

实证会计研究在很大程度上依赖 STATA 进行数据处理、统计分析和稳健性检验。该领域已经形成了一套标准化的方法:盈余质量模型、事件研究、针对监管变化的双重差分,以及用于处理内生性的工具变量策略。这些方法均通过一组相对稳定的 STATA 模式实现。

本指南介绍了顶级会计期刊(The Accounting Review、Journal of Accounting Research、Journal of Accounting and Economics 和 Review of Accounting Studies)中常用的核心 STATA 代码模式。这些模式源自财务报告、审计、税务和管理会计研究中常用的研究设计。

无论你是在估计可操纵应计项目、围绕盈余公告开展事件研究、检验审计师轮换对审计质量的影响,还是实施监管冲击分析,这些模式都能提供经过检验、便于审查的 STATA 实现方案。

数据准备

加载和清理 COMPUSTAT 数据
* ============================================================
* COMPUSTAT Annual Data Preparation for Accounting Research
* Standard preparation used across most empirical accounting papers
* ============================================================

* Load COMPUSTAT annual data
use "compustat_annual.dta", clear

* Keep relevant variables
keep gvkey fyear datadate at sale cogs xsga dp ib oancf act lct che dlc ///
     csho prcc_f ceq re dltt txp xrd ppegt ppent invt rect

* Set panel structure
destring gvkey, replace
xtset gvkey fyear

* --- Basic cleaning ---
* Drop financial firms (SIC 6000-6999) and utilities (SIC 4900-4999)
drop if inrange(sic, 6000, 6999) | inrange(sic, 4900, 4999)

* Require minimum observations
bysort gvkey: gen nobs = _N
drop if nobs < 3
drop nobs

* --- Generate common variables ---
* Total accruals (balance sheet approach)
gen total_accruals = (D.act - D.che) - (D.lct - D.dlc) - dp

* Total accruals (cash flow approach, preferred)
gen total_accruals_cf = ib - oancf

* Scale by lagged total assets
gen lag_at = L.at
gen ta_scaled = total_accruals_cf / lag_at
gen sale_scaled = sale / lag_at
gen ppe_scaled = ppent / lag_at
gen dsale = D.sale / lag_at
gen drec = D.rect / lag_at
gen roa = ib / lag_at

* Market value of equity
gen mve = csho * prcc_f

* Book-to-market ratio
gen btm = ceq / mve

* Leverage
gen leverage = (dlc + dltt) / at

* Firm size
gen size = ln(at)

* --- Winsorize at 1% and 99% ---
foreach var of varlist ta_scaled sale_scaled ppe_scaled roa btm leverage size {
    winsor2 `var', replace cuts(1 99)
}

* Label variables
label var ta_scaled "Total accruals / lagged assets"
label var roa "Return on assets"
label var btm "Book-to-market ratio"
label var leverage "Total debt / total assets"
label var size "Log(total assets)"

save "compustat_clean.dta", replace

盈余质量模型

修正 Jones 模型(Dechow 等,1995)
* ============================================================
* Modified Jones Model: Estimate discretionary accruals
* Standard model for earnings management research
* ============================================================

use "compustat_clean.dta", clear

* --- Step 1: Estimate non-discretionary accruals by industry-year ---
* Jones (1991) model estimated cross-sectionally

gen inv_lag_at = 1 / lag_at
gen dsale_drec = dsale - drec  // Modified Jones adjustment

* Estimate by 2-digit SIC and year (require >= 15 obs per group)
gen sic2 = floor(sic / 100)

* Cross-sectional estimation
gen da_mj = .
gen nda_mj = .

levelsof fyear, local(years)
foreach y of local years {
    levelsof sic2 if fyear == `y', local(industries)
    foreach ind of local industries {
        * Count observations in this industry-year
        count if sic2 == `ind' & fyear == `y' & !missing(ta_scaled, inv_lag_at, dsale_drec, ppe_scaled)
        if r(N) >= 15 {
            * Estimate Jones model
            quietly reg ta_scaled inv_lag_at dsale_drec ppe_scaled ///
                if sic2 == `ind' & fyear == `y', robust

            * Predict non-discretionary accruals
            quietly predict temp_nda if sic2 == `ind' & fyear == `y', xb
            quietly replace nda_mj = temp_nda if sic2 == `ind' & fyear == `y'
            drop temp_nda
        }
    }
}

* Discretionary accruals = Total accruals - Non-discretionary accruals
replace da_mj = ta_scaled - nda_mj

* Absolute discretionary accruals (common measure of earnings quality)
gen abs_da = abs(da_mj)

label var da_mj "Discretionary accruals (Modified Jones)"
label var abs_da "Absolute discretionary accruals"

save "accruals_data.dta", replace
业绩匹配的可操纵应计项目(Kothari 等,2005)
* ============================================================
* Kothari (2005): Performance-matched discretionary accruals
* Controls for correlation between performance and accruals
* ============================================================

* Add ROA to the Jones model
gen da_kothari = .

levelsof fyear, local(years)
foreach y of local years {
    levelsof sic2 if fyear == `y', local(industries)
    foreach ind of local industries {
        count if sic2 == `ind' & fyear == `y' & !missing(ta_scaled, inv_lag_at, dsale_drec, ppe_scaled, roa)
        if r(N) >= 15 {
            quietly reg ta_scaled inv_lag_at dsale_drec ppe_scaled roa ///
                if sic2 == `ind' & fyear == `y', robust
            quietly predict temp_res if sic2 == `ind' & fyear == `y', residuals
            quietly replace da_kothari = temp_res if sic2 == `ind' & fyear == `y'
            drop temp_res
        }
    }
}

gen abs_da_kothari = abs(da_kothari)
label var da_kothari "Discretionary accruals (Kothari)"
label var abs_da_kothari "Absolute DA (Kothari)"

事件研究

* ============================================================
* Short-window event study around earnings announcements
* Standard methodology for capital markets research
* ============================================================

use "crsp_daily_returns.dta", clear

* Merge with event dates
merge m:1 gvkey fyear using "earnings_dates.dta", keep(match) nogen

* --- Estimation window: [-250, -30] relative to announcement ---
gen event_day = date - rdq  // rdq = report date of quarterly earnings
keep if inrange(event_day, -250, 10)

* Estimate market model in estimation window
gen est_window = inrange(event_day, -250, -30)
gen event_window = inrange(event_day, -1, 1)  // 3-day window [-1, +1]

* Market model: R_i = alpha + beta * R_m + epsilon
bysort permno fyear: egen has_enough = total(est_window)
keep if has_enough >= 100  // Require 100+ days in estimation window

* Estimate market model parameters
gen alpha = .
gen beta_mkt = .

levelsof permno, local(firms)
foreach p of local firms {
    capture quietly reg ret mktrf if permno == `p' & est_window == 1
    if _rc == 0 {
        quietly replace alpha = _b[_cons] if permno == `p'
        quietly replace beta_mkt = _b[mktrf] if permno == `p'
    }
}

* Abnormal returns
gen ar = ret - (alpha + beta_mkt * mktrf)

* Cumulative abnormal returns [-1, +1]
bysort permno fyear (event_day): egen car_3day = total(ar) if event_window == 1

* Cross-sectional test
preserve
    keep if event_day == 0
    * t-test: Is average CAR different from zero?
    ttest car_3day == 0
    * Regression with controls
    reg car_3day surprise size btm, robust
restore

回归设定

带固定效应的标准面板回归
* ============================================================
* Standard regression specification for accounting research
* Includes firm and year fixed effects, clustered standard errors
* ============================================================

use "merged_analysis_data.dta", clear

* --- Main specification ---
* DV: Absolute discretionary accruals (earnings quality)
* Key IV: Big 4 auditor indicator

* Model 1: Pooled OLS (baseline, for comparison only)
reg abs_da big4 size leverage btm roa loss, robust
estimates store m1

* Model 2: Year fixed effects
reg abs_da big4 size leverage btm roa loss i.fyear, robust
estimates store m2

* Model 3: Industry + Year fixed effects
reg abs_da big4 size leverage btm roa loss i.sic2 i.fyear, robust
estimates store m3

* Model 4: Firm + Year fixed effects (preferred specification)
reghdfe abs_da big4 size leverage btm roa loss, absorb(gvkey fyear) ///
    cluster(gvkey)
estimates store m4

* Model 5: Firm + Year FE, two-way clustering (firm and year)
reghdfe abs_da big4 size leverage btm roa loss, absorb(gvkey fyear) ///
    cluster(gvkey fyear)
estimates store m5

* --- Output table ---
esttab m1 m2 m3 m4 m5 using "table_main.tex", replace ///
    star(* 0.10 ** 0.05 *** 0.01) ///
    b(%9.4f) se(%9.4f) ///
    stats(N r2 r2_a, fmt(%9.0g %9.4f %9.4f) ///
        labels("Observations" "R-squared" "Adj. R-squared")) ///
    title("Effect of Auditor Type on Earnings Quality") ///
    label booktabs

稳健性检验

倾向得分匹配
* ============================================================
* Propensity Score Matching (PSM) for endogeneity concerns
* Used when treatment assignment (e.g., Big 4 auditor) is not random
* ============================================================

* Step 1: Estimate propensity score
logit big4 size leverage btm roa loss age_firm, robust
predict pscore, pr

* Step 2: Common support check
gen cs = pscore >= 0.1 & pscore <= 0.9  // Trim extreme propensity scores

* Step 3: Nearest-neighbor matching (1:1, without replacement)
psmatch2 big4 size leverage btm roa loss if cs == 1, ///
    outcome(abs_da) neighbor(1) caliper(0.01) common

* Check covariate balance after matching
pstest size leverage btm roa loss, both

* Step 4: Re-estimate on matched sample
gen matched = _weight != .
reg abs_da big4 size leverage btm roa loss if matched == 1, robust
Heckman 选择模型
* ============================================================
* Heckman two-stage model for sample selection bias
* Example: Analyst coverage → Earnings quality
* ============================================================

* First stage: Selection equation (what determines analyst coverage?)
probit analyst_covered size btm roa institutional_ownership sp500 ///
    exchange_listed, robust

* Second stage: Outcome equation with inverse Mills ratio
heckman abs_da analyst_covered size leverage btm roa, ///
    select(analyst_covered = size btm roa institutional_ownership ///
           sp500 exchange_listed) ///
    twostep

可用于发表的输出

* ============================================================
* Generating publication-ready tables and statistics
* ============================================================

* Summary statistics table
estpost summarize abs_da big4 size leverage btm roa loss, detail
esttab using "table_sumstats.tex", replace ///
    cells("count mean sd p25 p50 p75") ///
    label booktabs title("Summary Statistics")

* Correlation matrix
pwcorr abs_da big4 size leverage btm roa, star(0.05) sig
estpost correlate abs_da big4 size leverage btm roa, matrix listwise
esttab using "table_corr.tex", replace unstack not noobs ///
    label booktabs title("Correlation Matrix")

* Univariate comparison (treatment vs. control)
ttest abs_da, by(big4) unequal
ranksum abs_da, by(big4)

最佳实践

  • 始终按公司聚类标准误(至少如此)以处理面板数据。审稿人越来越要求按公司和年份进行双向聚类。
  • 使用 reghdfe 处理高维固定效应。与 areg 或 xtreg, fe 相比,它速度更快、内存效率更高。
  • 报告经济显著性。 X 变化一个标准差会使因变量变化 Y%。
  • 纳入审稿人预期的所有稳健性检验: PSM、Heckman、安慰剂检验、熵平衡和替代变量定义。
  • 默认在 1% 和 99% 处缩尾; 并将 5%/95% 处缩尾的结果作为稳健性检验报告。
  • 使用 eststo 和 esttab 一致、自动地生成表格。切勿手动输入回归结果。

参考文献

  • Dechow, P. M., Sloan, R. G., & Sweeney, A. P. (1995). Detecting Earnings Management. The Accounting Review, 70(2), 193-225.
  • Kothari, S. P., Leone, A. J., & Wasley, C. E. (2005). Performance Matched Discretionary Accrual Measures. Journal of Accounting and Economics, 39(1), 163-197.
  • WRDS (Wharton Research Data Services) —— 会计与金融研究的标准数据平台
  • reghdfe documentation —— STATA 中的快速固定效应估计
  • Gow, I. D., Ormazabal, G., & Taylor, D. J. (2010). Correcting for Cross-Sectional and Time-Series Dependence in Accounting Research. The Accounting Review, 85(2), 483-512.

评论

支持 Markdown