专栏名称: 爬虫俱乐部
Stata技术控,编程技术咨询,数据讨论与分享,编程和实证培训。
目录
相关文章推荐
传媒招聘那些事儿  ·  【职业咨询/导师答疑】1V1模拟面试/语音答 ... ·  2 天前  
传媒招聘那些事儿  ·  【职业咨询/导师答疑】1V1模拟面试/语音答 ... ·  5 天前  
传媒招聘那些事儿  ·  哔哩哔哩:时尚活动运营 ·  4 天前  
传媒招聘那些事儿  ·  【全职岗位表格】在线文档持续更新:新闻媒体/ ... ·  5 天前  
51好读  ›  专栏  ›  爬虫俱乐部

事件研究大放送

爬虫俱乐部  · 公众号  ·  · 2018-03-19 14:41

正文

有问题,不要怕!点击推文底部“ 阅读原文 ”下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱 [email protected] ,我们会及时为您解答哟~

喜大普奔~爬虫俱乐部的 github 主站正式上线了!我们的网站地址是: https://stata-club.github.io ,粉丝们可以通过该网站访问过去的推文哟~

重磅推出:

爬虫俱乐部之前推出的线下培训,得到了各位老师的一致好评。为了更加方便大家学习,满足更多Stata用户的学习需求,爬虫俱乐部近期即将推出在线直播课程,敬请大家关注!

之前的推文 《免费事件研究,一片片从邮局寄来》 中,我们曾向大家介绍过事件研究的Stata程序,温故而知新!本篇推文对该程序进行了更新和完善,今天再和小编一起学习一下金融学研究必备基本功—事件研究。

事件研究法的 基本思想 是:事件研究是针对某一个事件窗口(Event Window)来计算 累计超额收益率(CAR) ,累计超额收益率是时间窗口期的实际收益与正常收益差值的累计相加。正常收益是使用CAPM模型或者FAma-French三因素模型对事件前的一段区间(Estimation Window)进行估计参数,然后计算事件窗口期没有发生此事件的正常收益。

一、事件研究准备阶段之事件列表的生成

首先我们要确定如下的事件列表,说明每只股票所对应事件发生的时间:

一般来说,这个事件列表来自于一个外部文件(比如text、EXCEL),需要读入Stata。为了简单说明问题,我们采取直接输入的事件列表:

clear

capture mkdir D:/事件研究/

input stkcd str10 Eventdate

2 "2015-10-20"

600900 "2015-04-14"

28 "2016-04-14"

600000 "2016-04-14"

601898 "2016-04-14"

601988 "2016-04-14"

601666 "2016-04-14"

end

事件列表列举后, 我们需要计算事件窗口期的股票累计超额收益率。由于Stata内存中只能读入一个数据文件,事件列表读入后,怎么读入其他的数据?对于这种情况,我们可以把这个事件列表保存到矩阵中,然后清空内存中的数据,读入交易数。当需要事件列表时只需调用矩阵即可。过程如下:

set matsize 500

cap gen Eventdate1=date(Eventdate,"YMD")

drop Eventdate

rename Eventdate1 Eventdate

format Eventdate %dCY-N-D // 日期从字符串型转换为数值型

sort stkcd Eventdate //  stkcd、Eventdate 分表为事件列表矩阵的两列

local N=_N // N为矩阵的行数

mkmat stkcd Eventdate, mat(event) // 事件列表数据存储为名为event的矩阵

二、事件研究准备阶段之获取收益率数据

目前,我们已经把事件列表存储到矩阵event里,该矩阵为N行2列,第一列是stkcd股票代码,第二列是evendate事件日期。接下来,可以直接读入股票的交易数据。

之前的推文 《免费事件研究,一片片从邮局寄来》 中,使用了cntrade命令获取个股收益率数据,市场收益率数据则需用cnindex命令获取。现在, cntrade 命令经过爬虫俱乐部的 更新后 ,可以直接下载市场收益率了,只需添加 index 选项即可,详见推文 《cntrade也可以下载股指数据啦》 ;另外,cntrade更新后下载得到的收益率数据为数值百分比,不需要从字符型转换数值型。

首先,检查我们是否已经安装了cntrade,如果没有需要按照以下,步骤如下:

cap which cntrade

if _rc!=0{

ssc install cntrade

}

获取 沪深300指数历史市场报价 数据:

cntrade 000300, index

keep date rmt

sort date

save "D:/事件研究/index.dta",replace

获取 个股的历史收益 数据(以万科股票000002为例):

clear

cntrade 2, path("D:/事件研究/")

keep stkcd date rit // 只保留我们所需的股票代码日期和收益率信息

sort date

使用 merge 命令通过date变量将个股收益率和市场收益率 横向合并 为一个文件,得到每日的个股收益率和市场收益率信息

merge 1:1 date using "D:/事件研究/index.dta"

drop _m

order stkcd date rit rmt

此时,我们的数据包括四个变量: stkcd date rit rmt

三、单只股票单个事件的事件研究

1. 定义事件期

我们需要构造一个相对的时间变量time,在事件日等于0,事件前为-1,-2, -3,... ,-200,事件后为1,2,3,……

我们可以将内存中的数据截断成两个,事件前的按日期倒排序,添加时间变量time=-_N,事件日以后的正排序,添加时间变量time=_N-1。整个过程如下:

根据事件列表,2015-10-20当日的事件E是万科的,可以确定事件日为2015-10-20:

local date = date("2015-10-20","YMD")

定义事件日`date’ 前的时间变量为-1,-2,-3...:

preserve

keep if date           //      保留事件日前的数据

gsort -date //             按日期倒排序

gen time=-_n //  生成事件变量为行数序号的相反数

keep if time>=-200 //         保留事件日前200天的数据

save "D:/事件研究/pre_event.dta", replace

restore

这里用到的 preserve restore 命令在之前的推文 《preserve restore---Stata的起死回生之术》 中介绍过,方便我们将数据分为事件前、事件后。

生成事件日后的时间变量0,1,2,........:

keep if date>=`date' //          保留事件日及其之后的数据

sort date

gen time = _n-1 //   生成时间变量,事件日为0,事件后为1,2,3...

keep if time<=10

事件日前后 数据合并 :

append using "D:/事件研究/pre_event.dta"

经过处理,现在我们得到了包括事件前200天及事件后10天的交易数据,共211天。

2. 计算异常收益率

假定估计窗口是(-200,-10),事件窗口是(-3,10)

在估计窗口用 个股收益率(rit) 市场交易率(rmt) 做回归,并估计事件窗口的异常收益率:

qui reg rit rmt if time<=-10

predict AR if time>=-3, r

保留事件窗口期的数据,使用 sum 命令累加得到累计超额收益率:

keep if time>=-3

sort time

gen CAR = sum(AR)

keep stkcd time CAR

四、通过循环对矩阵event存储的事件进行研究

矩阵event的`N’行2列是所有的事件,需要对每一行的事件进行分析,这时需要我们对行号进行循环,来达到事件列表里所有事件进行研究:

forval i=1/`N' { //      对矩阵行号进行循环

local date = scalar(event[`i',2]) //         提取该行的事件日期

local stkcd = scalar(event[`i',1]) //        提取该行的股票代码

dis `stkcd'

clear

cntrade `stkcd', path("D:/事件研究/")

keep stkcd date rit

drop in 1

sort date

merge m:m date using "D:/事件研究/index.dta"

drop _m

order stkcd date rit rmt

preserve

keep if date

gsort -date

gen time=-_n

keep if time>=-200

save "D:/事件研究/pre_event.dta", replace

restore

keep if date>=`date'

sort date

gen time = _n-1

keep if time<=10

append using "D:/事件研究/pre_event.dta"

qui reg rit rmt if time<=-10

predict AR if time>=-3, r

keep if time>=-3

sort time

gen CAR = sum(AR)

keep stkcd time CAR

save `i’.dta

}

五、post寄出事件研究的累计超额收益率

通过上述的程序,我们得到了事件列表中所有事件的累计超额收益率,如何把这些信息整理到一个文件中呢?如果将每次事件研究得到的数据文件一一合并起来,就太过繁琐了,更有效的办法是使用数据整理法宝级命令— post ,每次事件研究后,直接把需要的累计超额收益率的数据邮寄到特定的地址。

首先,我们把需要的数据信息放入local宏里,包括id(事件列表行号`i’)stkcd(股票代码)CAR1—CAR14(事件窗口期14天的累计异常收益率), 在循环过程中,行号和股票代码已经被放入宏中,因此我们只需要把14天累计异常收益率放进宏中即可。

forvalues m=1(1)14{

local CAR`m’ = CAR[`m’]

}

然后再通过post命令,把宏里的数据信息装入信封寄出即可。

先定义邮件,设定好 接收地址 :

postfile event id stkcd CAR1 CAR2 CAR3 CAR4 CAR5 CAR6 CAR7 CAR8 ///

CAR9 CAR10 CAR11  CAR12  CAR13 CAR14 ///

using "D:/事件研究/事件研究.dta",replace

再用post命令将我们循环得到的多次事件研究的累计超额收益率数据按照定义的格式邮寄到我们设定好的地址:

post event (`i') (`stkcd') (`CAR1') (`CAR2') ///

(`CAR3') (`CAR4') (`CAR5') (`CAR6') (`CAR7') ///

(`CAR8') (`CAR9') (`CAR10') (`CAR11') ///

(`CAR12') (`CAR13') (`CAR14')

一份份超额收益率的数据寄出后,我们关闭邮件系统即可:

postclose event

use D:/事件研究/事件研究.dta , 打开事件研究文件,每次事件研究得到的CAR值一目了然:

全部程序:

clear

capture mkdir "D:/事件研究/"

cap which cntrade

if _rc!=0{

ssc install cntrade

}

cntrade 000300, index

keep date rmt

sort date

save "D:/事件研究/index.dta",replace

capture postclose event

postfile event id stkcd CAR1 CAR2 CAR3 CAR4 ///

CAR5 CAR6 CAR7 CAR8 CAR9 CAR10 CAR11 CAR12  CAR13 CAR14 using "D:/事件研究/事件研究.dta",replace

*******Events

clear

input stkcd str10 Eventdate

2 "2015-10-20"

600900 "2015-04-14"

28 "2016-04-14"

600000 "2016-04-14"

601898 "2016-04-14"

601988 "2016-04-14"

601666 "2016-04-14"

end

set matsize 500

cap gen Eventdate1=date(Eventdate,"YMD")

drop Eventdate

rename Eventdate1 Eventdate

format Eventdate %dCY-N-D

sort stkcd Eventdate

*******Events Matrix

local N=_N

mkmat stkcd Eventdate, mat(event)

**save the event into a matrix called event

forval i=1/`N' {

local date = scalar(event[`i',2])

local stkcd = scalar(event[`i',1])

dis `stkcd'

clear

cntrade `stkcd', path("D:/事件研究/")

keep stkcd date rit

drop in 1

sort date

merge m:m date using "D:/事件研究/index.dta"

drop _m

order stkcd date rit rmt

preserve

keep if date

gsort -date

gen time=-_n

keep if time>=-200

save "D:/事件研究/pre_event.dta", replace

restore

keep if date>=`date'

sort date

gen time = _n-1

keep if time<=10

append using "D:/事件研究/pre_event.dta"

qui reg rit rmt if time<=-10

predict AR if time>=-3, r

keep if time>=-3

sort time

gen CAR = sum(AR)

keep stkcd time CAR

forvalues m=1(1)14{

local CAR`m’ = CAR[`m’]

}

post event (`i') (`stkcd') (`CAR1') (`CAR2') ///

(`CAR3') (`CAR4') (`CAR5') (`CAR6') (`CAR7') ///

(`CAR8') (`CAR9') (`CAR10') (`CAR11') ///

(`CAR12') (`CAR13') (`CAR14') ///

}

postclose event

use D:/事件研究/事件研究.dta,clear

注:此推文中的图片及封面(除操作部分的)均来源于网络!如有雷同,纯属巧合!

以上就是今天给大家分享的内容了,说得好就赏个铜板呗!有钱的捧个钱场,有人的捧个人场~。 另外,我们开通了苹果手机打赏通道,只要扫描下方的二维码,就可以打赏啦!

应广大粉丝要求,爬虫俱乐部的推文公众号打赏功能可以开发票啦,累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫。第一批发票已经寄到各位小主的手中,大家快来给小爬虫打赏呀~







请到「今天看啥」查看全文