本人的stata代码如下:
cd "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\stata数据"
*=======================================================================
* 基础数据整理
*=======================================================================
* 无风险利率采用一年期定期存款利率
use 无风险利率.dta, clear
* 生成交易月份变量
gen month=substr(date, 1, 7)
* 转化为月份数据
collapse (mean) Rf= Rf, by( month )
save Rf.dta, replace
* 市场收益率的计算
use 综合月市场回报率.dta, clear
* Market_type变量值的解释:5=沪深A股市场(不包含科创板、创业板), 10=沪深B股市场, 15=沪深AB股市场, 21=沪深A股和创业板, 31=沪深AB股和创业板, 37=沪深A股和科创板, 47=沪深AB股和科创板, 53=沪深A股和创业板和科创板, 63=沪深AB股和创业板和科创板,33=上证A股和科创板,20=深证A股和创业板, 69=沪深京A股市场,79=沪深京AB股市场,85=沪深京A股和创业板,95=沪深京AB股和创业板, 101=沪深京A股和科创板, 111=沪深京AB股和科创板, 117=沪深京A股和创业板和科创板,127=沪深京AB股和创业板和科创板。
* 选择沪深A股和创业板,即令market_type = 21。
keep if market_type==21
save Rm.dta, replace
* 根据中国上市制造业企业股票的日交易状态判断当月是否ST
use 个股日交易状态.dta, clear
* status[交易状态]变量值解释:1=正常交易,2=ST,3=*ST,4=S(2006年10月9日及之后股改未完成),5=SST,6=S*ST,7=G(2006年10月9日之前已完成股改),8=GST,9=G*ST,10=U(2006年10月9日之前股改未完成),11=UST,12=U*ST,13=N,14=NST,15=N*ST,16=PT
gen 是否ST或PT=inlist(status, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15, 16)
gen month=substr(date, 1, 7)
gen 是否ST=inlist(status, 2, 3, 5, 6, 8, 9, 11, 12, 14, 15)
gen 是否PT=inlist(status, 16)
* 转化为月度数据
collapse (max) 是否ST 是否PT 是否ST或PT, by(stock_code month)
save 是否ST.dta, replace
* 筛选出中国上市制造业企业每年12月底的市盈率倒数(EP)
use 原始EP.dta, clear
keep stock_code date EP_value
gen month = month(date)
gen year = year( date )
drop if month == 3 | month == 6 | month == 9
drop month
drop date
order stock_code year EP_value
save EP.dta, replace
* 筛选出在A股以及创业板上市的中国制造业企业
use 原始公司文件.dta, clear
*market_type变量值解释:1=上证A股市场 (不包含科创板),2=上证B股市场,4=深证A股市场(不包含创业板),8=深证B股市场,16=创业板, 32=科创板,64=北证A股市场。
drop if market_type != 1 & market_type != 4 & market_type != 16 & market_type != 64
save 公司文件.dta, replace
* 年末制造业企业流通市值(cmv)的单位转换
use 年度市值.dta
keep stock_code year cmv market_type
* 原数据集的流通市值单位为千元,将其转化为元
replace cmv=cmv*1000
destring year, replace
save 市值SIZE.dta, replace
* ESG得分预处理
use 原始ESG得分.dta, clear
gen month = mofd( date )
format month %tmCY-N
tostring month, replace usedisplayformat force
save ESG得分.dta, replace
*=======================================================================
* 收益率数据
*=======================================================================
* 计算收益率数据
use 月个股回报率.dta, clear
keep stock_code month Ri
merge m:1 month using Rf.dta, nogen keep(1 3)
merge m:1 month using Rm.dta, nogen keep(1 3) keepusing(Rm)
merge m:1 stock_code using 公司文件.dta, nogen keep(3) keepusing(list_date market_type)
merge 1:1 stock_code month using 是否ST.dta, nogen keep(1 3)
merge 1:1 stock_code month using ESG得分.dta, nogen keep(1 3) keepusing(ESG_rate)
* 将stock_code转化为数值型变量
egen stock_code_num = group(stock_code)
drop stock_code
rename stock_code_num stock_code
* 计算制造业企业月度股票超额收益率(%)
gen R_Rf=(Ri-Rf)*100
drop if R_Rf==.
* 计算市场因子MKT值(%)
gen MKT=(Rm-Rf)*100
* 选取t年5月至t+1年4月作为组合
gen m = monthly(month,"ym")
format m %tm
xtset stock_code m
gen group_year=year(dofm(m-4))
label var group_year 分组对应的年份
* 提取上市月份
gen list_month= monthly(substr(list_date, 1, 7),"YM")
format list_month %tm
* 截取2014-2023年的数据
gen year = year(dofm(m))
keep if year>=2014 & year<=2023
* 剔除股票上市后前6个月的数据(包括上市月份)
gen month_gap=m-list_month
drop if month_gap<6
* 剔除ST股
drop if 是否ST或PT==1
* ESG得分缺失值清洗
drop if ESG_rate==.
save 收益率数据.dta, replace
*=======================================================================
* 分组数据
*=======================================================================
use 收益率数据.dta, clear
keep stock_code group_year
duplicates drop stock_code group_year, force
save prep.dta, replace
* 匹配市值和EP市值数据
use 市值SIZE.dta, clear
merge m:1 stock_code year using EP.dta, nogen keep(1 3)
* 使用上一年年末的数据来分组
replace year=year+1
gen size=cmv
egen stock_code_num = group(stock_code)
drop stock_code
rename stock_code_num stock_code
* 剔除EP值为负的股票
drop if EP_value<0
drop if EP_value==.
rename year group_year
* 剔除没有收益率数据的观测值
merge 1:1 stock_code group_year using prep.dta, nogen keep(3)
save 分组数据.dta, replace
*=======================================================================
* 分组崳
*=======================================================================
use 分组数据.dta, clear
* 剔除市值最小的30%的股票
egen 市值10等分=xtile(size), n(10) by(group_year)
drop if 市值10等分<=3
* 将制造业企业股票按市值SIZE从大到小排序,以中位数为分组临界点进行分组
* 分成大市值组(B)和小市值组(S)
egen SIZE_group=xtile(size), n(2) by(group_year)
gen 市值分组="S" if SIZE_group==1
replace 市值分组="B" if SIZE_group==2
* 将制造业企业股票按EP值从大到小排序,以第30个和第70个百分位数为临界点进行分组
* 分为高EP值组(V)、中EP值组(M)、低EP值组(G)
egen EP_group=xtile(EP_value), n(10) by(group_year)
gen EP值分组="G" if EP_group<=3
replace EP值分组="M" if EP_group>3 & EP_group<=7
replace EP值分组="V" if EP_group>7
* 构建因变量的25个投资组合
egen SIZE_group_5=xtile(size), n(5) by(group_year)
egen EP_group_5=xtile(EP_value), n(5) by(group_year)
keep stock_code group_year 市值分组 EP值分组 SIZE_group_5 EP_group_5 size
save 分组结果.dta, replace
*==== 分25组求收益率均值=====
* 求25个投资组合的月市值加权收益率
use 收益率数据.dta, clear
merge m:1 stock_code group_year using 分组结果.dta, nogen keep(3)
* 计算每个投资组合每月的月市值加权收益率Rij
bys EP_group_5 SIZE_group_5 month : egen size_prop = pc(size), prop
gen Rij=R_Rf*size_prop
collapse (sum) Rij, by(EP_group_5 SIZE_group_5 month )
save 25个投资组合的月市值加权收益率.dta, replace
* 计算每个投资组合从2015年6月至2023年12月共103个月的月市值加权收益率均值
collapse (mean) Rij , by( SIZE_group_5 EP_group_5 )
* 将结果转化成5*5的矩阵
spread SIZE_group_5 Rij
export excel "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\25个投资组合的月市值加权收益率均值.xlsx", firstrow(var) replace
*= 计算High-Low Newey-West t检验
use 25个投资组合的月市值加权收益率.dta, clear
spread EP_group_5 Rij
egen t=group( month )
xtset SIZE_group_5 t
* 滞后期数根据 q=4*(240/100)^(2/9)计算
di 4*(240/100)^(2/9)
* 滞后期数选择4
* 验证第五组与第一组差异,求newey t值
gen diff= Rij5 - Rij1
forv i=1/5 {
qui newey diff if SIZE_group_5 ==`i', lag(4) force
est store r1_`i'
}
esttab r1_* , nogap replace keep(_cons) b(3) t(3) star(* 0.1 ** 0.05 *** 0.01)
esttab r1_* using "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\【Rij】Newey-West_T检验.rtf", nogap replace keep(_cons) b(3) t(3) star(* 0.1 ** 0.05 *** 0.01)
*==== 分25组求ESG得分均值=====
use 收益率数据.dta, clear
merge m:1 stock_code group_year using 分组结果.dta, nogen keep(3)
* 计算每个投资组合每月的月市值加权ESG得分
bys EP_group_5 SIZE_group_5 month : egen size_prop = pc(size), prop
gen ESG_ij=ESG_rate*size_prop
collapse (sum) ESG_ij, by(EP_group_5 SIZE_group_5 month )
* ESG得分标准化
egen std_ESG_ij = std(ESG_ij)
drop ESG_ij
rename std_ESG_ij ESG_ij
save 25个投资组合的月市值加权ESG得分.dta, replace
* 计算每个投资组合从2015年6月至2023年12月共103个月的月市值加权ESG得分
collapse (mean) ESG_ij , by( SIZE_group_5 EP_group_5 )
* 将结果转化成5*5的矩阵
spread SIZE_group_5 ESG_ij
export excel "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\25个投资组合的月市值加权ESG得分均值.xlsx", firstrow(var) replace
*= 计算High-Low Newey-West t检验
use 25个投资组合的月市值加权ESG得分.dta, clear
spread EP_group_5 ESG_ij
egen t=group( month )
xtset SIZE_group_5 t
* 滞后期数根据 q=4*(240/100)^(2/9)计算
di 4*(240/100)^(2/9)
* 滞后期数选择4
* 验证第五组与第一组差异,求newey t值
gen diff_1= ESG_ij5 - ESG_ij1
forv i=1/5 {
qui newey diff_1 if SIZE_group_5 ==`i', lag(4) force
est store e1_`i'
}
esttab e1_* , nogap replace keep(_cons) b(3) t(3) star(* 0.1 ** 0.05 *** 0.01)
esttab e1_* using "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\【ESG_ij】Newey-West_T检验.rtf", nogap replace keep(_cons) b(3) t(3) star(* 0.1 ** 0.05 *** 0.01)
*=======================================================================
* 构建因子
*=======================================================================
use 收益率数据.dta, clear
merge m:1 stock_code group_year using 分组结果.dta, nogen keep(3)
* 将市值和EP两个指标交叉2*3组
gen comb= 市值分组 + EP值分组
* 计算各组合每一期的市值加权平均收益率以及ESG得分
bys comb month : egen p1=pc( size ), prop
bys comb month : egen c_Ri=sum(p1*R_Rf)
collapse (mean) c_Ri , by( comb 市值分组 EP值分组 month MKT)
* 生成变量便于计算SMB和VMG
foreach i in SV SM SG BV BM BG {
bys month : egen _`i'=mean( c_Ri ) if comb=="`i'"
bys month : egen `i'=mean(_`i')
drop _`i'
}
keep month MKT SV SM SG BV BM BG
duplicates drop month MKT SV SM SG BV BM BG, force
* 计算SMB
gen SMB=(SV+SM+SG)/3 -(BV+BM+BG)/3
* 计算VMG
gen VMG=(SV+BV)/2- (SG+BG)/2
keep month MKT SMB VMG
save 三因子数据.dta, replace
*===============================================================================
* 制造业企业股票池的月市值加权ESG得分
*===============================================================================
use 收益率数据.dta, clear
keep stock_code month group_year ESG_rate
merge m:1 stock_code group_year using 分组数据.dta, nogen keep(3)
bys month : egen p0=pc(size), prop
bys month : egen ESG_=sum(p0*ESG_rate)
* ESG得分标准化
egen ESG= std(ESG_)
keep month ESG
duplicates drop month ESG, force
save 股票池月市值加权ESG得分.dta, replace
*===============================================================================
* 数据汇总
*===============================================================================
use 25个投资组合的月市值加权收益率.dta, clear
merge 1:1 month EP_group_5 SIZE_group_5 using 25个投资组合的月市值加权ESG得分.dta, nogen
merge m:1 month using 三因子数据.dta, nogen keep(1 3)
save 数据汇总.dta, replace
*===============================================================================
* 实证分析
*===============================================================================
*=====描述性统计=====
use 股票池月市值加权ESG得分.dta, clear
merge 1:1 month using 三因子数据.dta, nogen
sum2docx ESG MKT SMB VMG using 描述性统计.docx, replace stats (N mean(%9.3f) sd(%9.3f) min(%9.3f) max(%9.3f)) title("表5-1 描述性统计")
* 更全面的描述性统计【带偏度和峰度】
*outreg2 using 全面的描述性统计.rtf, replace sum(detail) title("全面描述性统计")
*=====相关性分析=====
qui estpost correlate MKT SMB VMG ESG, matrix
esttab ,unstack not noobs compress nogaps replace star(* 0.1 ** 0.05 *** 0.01) b(%8.3f) title(esttab_Table: correlation coefficient matrix)
esttab using "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\相关性分析.rtf", unstack not noobs compress nogaps replace star(* 0.1 ** 0.05 *** 0.01) b(%8.3f) title(esttab_Table: correlation coefficient matrix)
*也可:pwcorr_a ESG MKT SMB VMG
*=====ADF检验======
gen m = monthly(month, "ym")
tsset m
foreach var of varlist ESG MKT SMB VMG {
dfuller `var'
}
* ESG变量不平稳,考虑一阶差分并再次检验
gen d1_ESG = d.ESG
dfuller d1_ESG
* d1_ESG通过检验,因此用d1_ESG代替ESG
drop ESG
rename d1_ESG ESG
drop if ESG==.
save 三因子+ESG.dta, replace
*=====再次进行相关性分析=====
qui estpost correlate MKT SMB VMG ESG, matrix
esttab ,unstack not noobs compress nogaps replace star(* 0.1 ** 0.05 *** 0.01) b(%8.3f) title(esttab_Table: correlation coefficient matrix)
esttab using "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\【一阶差分后】相关性分析.rtf", unstack not noobs compress nogaps replace star(* 0.1 ** 0.05 *** 0.01) b(%8.3f) title(esttab_Table: correlation coefficient matrix)
*也可:pwcorr_a ESG MKT SMB VMG
*================================分25组回归=====================================
cd "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\stata数据"
use 数据汇总.dta, clear
*构建ESG·MKT交叉项进行回归
gen ESG_MKT = ESG_ij*MKT
* 分组回归计算各组的回归系数,使用Newey-West t统计量
bys SIZE_group_5 EP_group_5 : asreg Rij MKT SMB VMG ESG_MKT , se rmse newey(4)
keep SIZE_group_5 EP_group_5 _Nobs _rmse _R2 _adjR2 _b_MKT _b_SMB _b_VMG _b_ESG_MKT _b_cons _se_MKT _se_SMB _se_VMG _se_ESG_MKT _se_cons
duplicates drop SIZE_group_5 EP_group_5 _Nobs _rmse _R2 _adjR2 _b_MKT _b_SMB _b_VMG _b_ESG_MKT _b_cons _se_MKT _se_SMB _se_VMG _se_ESG_MKT _se_cons, force
* 计算t值和p值 标注星号
* 计算t值和p值 标注星号
foreach i in cons MKT SMB VMG ESG_MKT {
gen t_`i'=_b_`i'/_se_`i'
gen p_`i'=ttail(_Nobs, abs(t_`i'))*2
gen star_`i'="*" if p_`i'<0.1
replace star_`i'="**" if p_`i'<0.05
replace star_`i'="***" if p_`i'<0.01
}
export excel using "C:\Users\Henry Lin\Desktop\数据\制造业\主回归\实证分析\回归草稿\主线\(不差分)【直接】ESG四因子模型\结果\【ESG·MKT交叉】25分组回归结果.xlsx", firstrow(var) replace
求救大佬看看我是哪里出了问题,我检查了"数据汇总.dta"这个文件的数据,发现好像没有排序问题。。。