use eventda, clear
drop comnam
tsset company_id date
sort company_id date
by company_id: gen datenum=_n //定义新的日期变量,取值为 1,2,3,...
by company_id: gen target=datenum if date==event_date // 标定事件日
egen td = min(target), by(company_id) // 扩充target的观察值
gen dif = datenum-td // 以事件日0为基准定义日期
list comp date event_date datenum target td dif in 1/20
*------
*-2.2.1 定义事件窗口 [-2, 2],即时间前后各两天
by company_id: gen event_window=1 if (dif>=-2 & dif<=2)
egen count_event_obs=count(event_window), by(company_id)
*------
*-2.2.2 定义估计窗口 [-60, -30]
by company_id: gen estimation_window = 1 if (dif<-30 & dif>=-60)
egen count_est_obs = count(estimation_window), by(company_id)
* 如果 count_est_obs<30,该公司将被删除,因为没有足够的样本来估计正常回报率
*------
*-2.2.3 用 0 和 1 区分事件窗口和非事件窗口
list comp date target dif *window in 1/30, sep(0)
list comp date target dif *window in 290/360, sep(0)
replace event_window = 0 if event_window==.
replace estimation_window = 0 if estimation_window==.
list comp date target dif *window in 1/30, sep(0)
list comp date target dif *window in 290/360, sep(0)
*------
*-2.2.4 删除样本数不足的公司
*-事件窗口观察值不足5天的公司
tab company_id if count_event_obs<5
xtdes if count_event_obs<5, p(0) // 计算此类公司数目
drop if count_event_obs<5
*-估计窗口观察值不足30的公司
tab company_id if count_est_obs<30
xtdes if count_est_obs<30, p(0) // 计算此类公司数目
drop if count_est_obs<30
cap drop predicted_return
gen predicted_return=. // 用于存放正常回报率的变量
cap drop id
egen id=group(company_id) // 重新定义公司代码为 1,2,3...,便于执行循环程序
qui tab id
local N = r(r) // 记录公司数目
forvalues i=1(1)`N' {
*-在估计窗口内估计市场模型
qui reg ret market_return if (id==`i' & estimation_window==1)
*-得到全样本范围内的正常回报率,即 market_return 的全样本拟合值
predict p if id==`i'
*-在事件窗口内计算正常回报率
replace predicted_return = p if (id==`i' & event_window==1)
drop p // 把相关结果记录到了predicted_return变量中,变量p已经无用
}
*-计算超额回报率 Abnormal Returns
gen abnormal_return = ret - predicted_return if event_window==1
*-计算累积超额回报率 CAR_id: sum of each firm (简单加总)
sort id date
by id: egen CAR_id = sum(abnormal_return) // egen
list id date dif abnormal_return CAR_id if (event_window==1 & id==1)
*-计算累积超额回报率 CAR_date: sum according distance from event day(按时间累积加总)
cap drop CAR_date // gen
bysort comp: gen CAR_date = sum(abnormal_return) if event_window==1
list id date dif abnormal_return CAR_date if (event_window==1 & id ==1)