python做事件研究法_35行代码搞定事件研究法(上)
作者簡(jiǎn)介:
祝小宇,個(gè)人公眾號(hào):大貓的R語言課堂
這期大貓課堂將會(huì)教大家如何用35行R代碼寫出最有效率的事件研究法。
注意,本代碼主要使用data.table完成,關(guān)于data.table包的相應(yīng)知識(shí)會(huì)在涉及的時(shí)候進(jìn)行講解。在以后的課堂中,我們會(huì)重點(diǎn)介紹data.table這個(gè)包。
1 事件研究法的基本過程
首先,我們先來回顧一下事件研究法的基本過程:
根據(jù)上圖,T日是事件日,事件研究法的目的是計(jì)算事件日前后若干日超額收益(CAR)之和,而超額收益的定義為該股當(dāng)日收益減去模型收益之差。如果我們用C1與C2標(biāo)記CAR窗口期,用M1與M2標(biāo)記模型的估計(jì)期(C1、C2、M1、M2都為正數(shù),定義見上圖),則上圖的含義為:
在?[T - M1, T - M2]?的區(qū)間內(nèi)估計(jì)市場(chǎng)模型,并在?[T - C1, T + C2]?的區(qū)間內(nèi)計(jì)算超額收益率。
在這里,我們姑且用最簡(jiǎn)單的市場(chǎng)模型來估計(jì)收益,即:
r = alpha + beta * (r - rm)
其中,r?表示個(gè)股每日的收益率,rm?表示對(duì)應(yīng)日期市場(chǎng)指數(shù)的收益率。
2 樣例數(shù)據(jù)集
一切沒有栗子的講解都是耍流氓,現(xiàn)在我們就假設(shè)需要對(duì)如下數(shù)據(jù)集運(yùn)用事件研究法:
其中,stk.id表示股票代碼,date是日期,r表示個(gè)股收益率,rm表示市場(chǎng)收益率,event.flg是事件日標(biāo)識(shí)。如果當(dāng)天不是事件日,event.flg為0,否則為1。(似乎莫名其妙立了flag……)由上圖可知,只有在第30行發(fā)生了事件(用紅框框出)。
不妨進(jìn)一步假設(shè)C1 = C2 = 1, M1 = 10, M2 = 5。也即我們的CAR窗口期為[T - 1, T + 1],模型的估計(jì)期為[T - 10, T?- 5]。當(dāng)然那么短的模型估計(jì)期(5天)是非常不現(xiàn)實(shí)的,這里僅為了舉例方便這樣設(shè)定。
3 舉一個(gè)詳細(xì)的栗子
OK,既然栗子也有了,我們就要正式開工啦。本著從特殊到一般的原則,在這一講中,我們首先假設(shè)現(xiàn)在只有一個(gè)事件日。針對(duì)這一個(gè)事件日,大貓會(huì)給出一個(gè)叫做?do_car()?的自定義函數(shù)計(jì)算其對(duì)應(yīng)的超額收益。當(dāng)以后出現(xiàn)多個(gè)事件日時(shí),我們只要對(duì)每個(gè)事件日都調(diào)用一次 do_car() 函數(shù)就可以了。
這種“先把任務(wù)分解為任務(wù)單元,為每個(gè)任務(wù)單元寫一個(gè)函數(shù),然后再批量調(diào)用函數(shù)”的方法,希望大家好好掌握哦!
既然我們的目標(biāo)是寫一個(gè)函數(shù) do_car(),那么其肯定有參數(shù)。為了計(jì)算超額收益,我們需要以下四個(gè)輸入變量:1)個(gè)股收益向量 r, 2)市場(chǎng)收益向量 rm,3)日期向量,4)事件日發(fā)生的序號(hào) n。因此這個(gè) do_car() 大致會(huì)長(zhǎng)這個(gè)樣子:
do_car
}
那么如何把函數(shù)的主體填充進(jìn)去,從而計(jì)算單個(gè)事件日對(duì)應(yīng)的超額收益呢?大貓給出以下三個(gè)步驟:
Step I. 先定位事件日,然后根據(jù)給定的參數(shù)分別截取出模型估計(jì)期 [T - 10, T?- 5] 以及CAR窗口期 [T - 1, T + 1] 的收益率 r、rm
Step II. 根據(jù)模型估計(jì)期的 r 與 rm 數(shù)據(jù)估計(jì)收益率模型的參數(shù) alpha,beta,并計(jì)算超額收益率
Step III. 輸出最終結(jié)果
Step I:截取收益率向量
我們用n來標(biāo)記事件日的序號(hào)。例如在我們的例子中,第30天發(fā)生了事件,因而n=30。需要注意的是在我們的例子中 n 是一個(gè)標(biāo)量,下節(jié)課中我們會(huì)把n拓展為向量,也即引入多個(gè)事件日。
確定了事件日序號(hào)之后,我們就可以用他來截取收益率向量了。模型估計(jì)期的個(gè)股收益向量為?r[n - m2, n - m1],(n - m2表示截取起點(diǎn),n - m1表示截取的終點(diǎn)),我們將其命名為 r.model。同理,模型估計(jì)期對(duì)應(yīng)的市場(chǎng)收益率的向量為?rm[n - m2, n - m1],我們將其命名為 rm.model。類似的,我們可以分別截取出CAR窗口期的收益率向量。代碼如下:
i1
i2
i3
i4
r.model
rm.model
r.car
rm.car
其中,r 表示個(gè)股收益,rm 表示市場(chǎng)收益,后綴model表示模型估計(jì)期,后綴car表示CAR窗口期。
Step II:估計(jì)模型,計(jì)算超額收益率
得到了r.model, rm.model 這兩個(gè)變量,我們就可以進(jìn)行收益模型的估計(jì)了。我們使用R內(nèi)置的多元線性回歸函數(shù):
> model coef
> ars
先來看第一行。其中,lm是回歸函數(shù),“~”符號(hào)左邊的是因變量r.model,右邊的是自變量?I(r.model - rm.model),最后得到的回歸模型命名為“model”。R默認(rèn)回歸中有常數(shù)項(xiàng),因而在公式中不需要顯式表示。另外,函數(shù)I()表示要把r.model - rm.model的結(jié)果作為一個(gè)變量來看待。
再來看第二行。要知道在R中,線性回歸的結(jié)果是一個(gè)類名為“l(fā)m”的對(duì)象,這個(gè)對(duì)象包含了回歸結(jié)果的系數(shù)、p值、殘差等等元素。而coef()函數(shù)的作用就是提取回歸結(jié)果的系數(shù)。
最后看第三行。這一行的作用是用估計(jì)得到的模型預(yù)測(cè)CAR窗口期股票的收益率。predict()函數(shù)用來預(yù)測(cè)模型。第一個(gè)參數(shù)model指出了預(yù)測(cè)所依據(jù)的模型(就是我們上面估計(jì)得到的model),第二個(gè)參數(shù)指定了自變量,其中“r.model = r.car”表示把model中的r.model變量用r.car變量代替,類似的,"rm.model = rm.car"表示把model中的rm.model變量替換成rm.car。最后,我們用股票的實(shí)際收益率(r.car)減去由模型計(jì)算得到的收益率(predict()函數(shù)計(jì)算的結(jié)果),就能得到股票的超額收益(ars, abnormal returns)。需要注意的是,剛才提到的ars, r.car, r.model等變量都是向量,而不是標(biāo)量。
Step III:輸出最終結(jié)果
得到了超額收益率向量ars,我們需要確定最終輸出的結(jié)果應(yīng)該是什么樣子。一般來說,對(duì)于每一個(gè)事件日(非事件日我們不輸出結(jié)果),我們需要保留股票代碼stk.id、事件日date、該事件日對(duì)應(yīng)的收益率模型系數(shù)coef,以及該事件日窗口期間的超額收益。因此最終輸出結(jié)果應(yīng)該大致長(zhǎng)下面這個(gè)樣子:
關(guān)于上面這個(gè)輸出結(jié)果,有以下三點(diǎn)需要注意:
1. 圖中每一行都對(duì)應(yīng)一個(gè)事件日,非事件日不輸出結(jié)果。上圖中說明6月17日發(fā)生了一個(gè)事件。
2. ars是超額收益率向量,因?yàn)槲覀兊睦又邪殉~收益率區(qū)間定為 T 日前后各一天,因此 ars 共有三個(gè)元素。注意,我們這里沒有直接輸出加總后的CAR,而是輸出超額收益向量ars。這是因?yàn)檩敵龀~收益向量便于我們后期進(jìn)行各種復(fù)雜的計(jì)算。
3. coef、ars都是向量
這一步對(duì)應(yīng)的代碼是:
list(date = date[n], coef = list(coef), ars = list(ars))
這一行代碼指定了我們需要輸出的三個(gè)變量:事件日、收益率模型系數(shù)以及超額收益。其中,coef = list(coef)的含義是把向量coef打包成一個(gè)list類型的變量,并命名為coef。date = date[n]的含義是選取date變量的第n個(gè)元素(也就是事件日),并命名為date。最外面的list()則把其中的三個(gè)元素打包成一個(gè)大的list。值得一提的是,我們?cè)谶@里運(yùn)用了把向量打包成list的這個(gè)小技巧,這一技巧在進(jìn)行回歸計(jì)算時(shí)非常有用,其作用以及應(yīng)用場(chǎng)景將會(huì)在以后詳細(xì)講述。現(xiàn)在只要知道它用來輸出結(jié)果就可以了。
將step I ~ III 歸納為函數(shù)
把 step I?至 step III 歸納成函數(shù)的話就是:已知個(gè)股收益率向量r、市場(chǎng)收益率向量rm、日期向量date,以及事件日的序號(hào)n(標(biāo)量),我們就可以用以下函數(shù)計(jì)算對(duì)應(yīng)事件日的超額收益率向量ars——
do_car m2)? ? if (n - m1 < 0) {? ? ? ? cat("n =", n, "is too small \n")? ? } else if (n + c2 > length(r)) {? ? ? ? cat("n =", n, "is too large \n")? ? } else {? ? ? ? i1
其中,(n - m1 < 0)以及(n + c2 > length(r)) 這兩條語句的作用是:如果事件日出現(xiàn)在收益率向量的太前面或者太后面,以至于向前向后追溯無法滿足估計(jì)模型或者CAR窗口期的要求,那么該事件日將被剔除。
下期預(yù)告
至此,我們已經(jīng)學(xué)會(huì)如何針對(duì)單一事件日計(jì)算超額收益了。然而現(xiàn)實(shí)生活中我們往往要計(jì)算多個(gè)股票多個(gè)事件日的超額收益,這時(shí)應(yīng)該怎么做?小伙伴們不用擔(dān)心,其實(shí)只需要添加幾行代碼就可以了。具體做法,就請(qǐng)期待下一次的大貓課堂——35行代碼搞定事件研究法(下)
公眾號(hào)后臺(tái)回復(fù)關(guān)鍵字即可學(xué)習(xí)回復(fù)爬蟲爬蟲三大案例實(shí)戰(zhàn)
回復(fù)Python1小時(shí)破冰入門
回復(fù)數(shù)據(jù)挖掘R語言入門及數(shù)據(jù)挖掘
回復(fù)人工智能三個(gè)月入門人工智能
回復(fù)數(shù)據(jù)分析師數(shù)據(jù)分析師成長(zhǎng)之路
回復(fù)機(jī)器學(xué)習(xí)機(jī)器學(xué)習(xí)的商業(yè)應(yīng)用
回復(fù)數(shù)據(jù)科學(xué)數(shù)據(jù)科學(xué)實(shí)戰(zhàn)
回復(fù)常用算法常用數(shù)據(jù)挖掘算法
總結(jié)
以上是生活随笔為你收集整理的python做事件研究法_35行代码搞定事件研究法(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: http服务(nginx、apache)
- 下一篇: python爬取微博热搜显示到折线图_P