量化交易30天
本系列文章是紀錄一位量化交易新手的學習過程,除了基礎的Python語法不說明,其他金融相關的東西都會一步步地說明,希望讓更多想學習量化交易但是沒有學過相關金融知識的朋友們,透過這系列的文章,能夠對量化交易略知一二,也歡迎量化交易的高手們多多交流。
上一篇的Jensen alpha公式,是再分析資產是否有超額報酬,這篇就要實際拿個股來測試看看,怎麼將價格資料帶入,計算alpha、beta。
# 回顧一下公式
Ra = α + Rf + β * ( Rm - Rf ) + 誤差項
如果將上面公式的Rf移到等號左邊,會變成下面這個公式
( Ra - Rf ) = α + β * ( Rm - Rf ) + 誤差項
這個式子可以看成下面這條
Y = a + bX + 誤差項
Y:Ra - Rf,每天的報酬率扣掉無風險報酬率
X:Rm - Rf,市場報酬率扣掉無風險報酬率
而我們之所以用CAPM,就是想知道資產跟市場報酬的關係,所以想求出計算式中的 a 及 b,但是由於每天的Y及X是會一直變動的,所以我們不太可能透過一組(X, Y)數組就算出 a 及 b,只能用一堆(X, Y)數組去估計,這邊就需要運用統計學的知識了。
要找出X跟Y的關係,可以用回歸模型來找找看,因為只有兩個變數X,Y,所以只需要OLS即可,OLS的概念大概就是在下圖這些紅點中,找出一條藍色直線,最小化每一點跟這條線的垂直距離的平方和。
要套用CAPM,我們需要有一檔商品的報酬率、市場報酬率,以及無風險報酬率,這邊就用AAPL來練習,市場報酬則是採用SPY為基準,無風險利率則是採用美國十年期公債殖利率作為參考。
import os
import pandas_datareader as pdr
SPY = pdr.get_data_tiingo('SPY', api_key='YOUR API KEY')
AAPL = pdr.get_data_tiingo('AAPL', api_key='YOUR API KEY')
# SPY 2019 日報酬率
SPY = SPY.reset_index(level=[0,1])
SPY.index = SPY['date']
SPY_adj = SPY.iloc[:,7:11]
SPY_adj.columns = ['Close','High','Low','Open']
SPY_Close_adj = SPY_adj.Close
ret1 = SPY_Close_adj.shift(-2) / SPY_Close_adj.shift(-1)
spy_daily_ret = ret1 - 1
spy_daily_ret_2019 = spy_daily_ret['2019']
# AAPL 2019 日報酬率
AAPL = AAPL.reset_index(level=[0,1])
AAPL.index = AAPL['date']
AAPL_adj = AAPL.iloc[:,7:11]
AAPL_adj.columns = ['Close','High','Low','Open']
AAPL_Close_adj = AAPL_adj.Close
ret1 = AAPL_Close_adj.shift(-2) / AAPL_Close_adj.shift(-1)
aapl_daily_ret = ret1 - 1
aapl_daily_ret_2019 = aapl_daily_ret['2019']
# 整合成一個dataframe
import pandas as pd
ret_data = pd.concat([aapl_daily_ret_2019,spy_daily_ret_2019], axis = 1)
ret_data.columns = ['AAPL', 'SPY']
ret_data
AAPL SPY
date
2019-01-02 00:00:00+00:00 0.042689 0.033496
2019-01-03 00:00:00+00:00 -0.002226 0.007885
2019-01-04 00:00:00+00:00 0.019063 0.009395
2019-01-07 00:00:00+00:00 0.016982 0.004673
2019-01-08 00:00:00+00:00 0.003196 0.003528
... ... ...
2019-12-24 00:00:00+00:00 -0.000379 -0.000248
2019-12-26 00:00:00+00:00 0.005935 -0.005513
2019-12-27 00:00:00+00:00 0.007307 0.002429
2019-12-30 00:00:00+00:00 0.022816 0.009352
2019-12-31 00:00:00+00:00 -0.009722 -0.007572
上面這張表就是2019年AAPL與SPY的日報酬率資料
因為2019年共有252個交易日,所以要將年利率取252次方根
# risk free return
rf_ret = 1.0078 ** ( 1 / 252 ) - 1
可以對照上面的數字,會有些微的差距。
Ex_ret = ret_data - rf_ret
Ex_ret
AAPL SPY
date
2019-01-02 00:00:00+00:00 0.042659 0.033465
2019-01-03 00:00:00+00:00 -0.002257 0.007854
2019-01-04 00:00:00+00:00 0.019032 0.009365
2019-01-07 00:00:00+00:00 0.016951 0.004643
2019-01-08 00:00:00+00:00 0.003165 0.003497
... ... ...
2019-12-24 00:00:00+00:00 -0.000410 -0.000279
2019-12-26 00:00:00+00:00 0.005904 -0.005544
2019-12-27 00:00:00+00:00 0.007276 0.002398
2019-12-30 00:00:00+00:00 0.022785 0.009321
2019-12-31 00:00:00+00:00 -0.009753 -0.007603
import matplotlib.pyplot as plt
plt.rcParams['axes.unicode_minus']=False
plt.scatter(Ex_ret.values[:,0],Ex_ret.values[:,1])
plt.title('AAPL return and SPY return')
下面就是要用這個散佈圖裡面,用OLS去估計一條直線,來代表AAPL與SPY的關係。
statsmodels是python的一個統計函數庫,裡面就有OLS模組可以直接套用,非常方便。
import statsmodels.api as sm
model=sm.OLS(Ex_ret.AAPL[1:],sm.add_constant(Ex_ret.SPY[1:]))
result=model.fit()
result.summary()
根據上述的計算,可以求出:
Ra - Rf = 0.0014 + 1.464 * ( Rm - Rf ) + 誤差項
觀察統計數據,SPY的p-value小於0.05,表示風險係數beta顯著不等於0,beta取值1.464表示AAPL這檔個股的波動度高於SPY,另外alpha取值0.0014表示有存在超額報酬率,且p-value小於0.05,表示alpha顯著不等於0。
本篇總結
這篇實作用CAPM理論去計算AAPL跟SPY的關係,用到了一些統計學的概念,包含最小平方和、假設檢定...等等,算是有點深入,應該會需要消化一下或是google相關知識,不過還是挺有趣的。
P.S.
如果大家對於量化交易有興趣的話,我自己有上過以下這門課,課程內容從串接股市資料API、儲存至資料庫、將自己的策略轉化成程式碼、自動下單,並且可以把整個流程自動化,每天早上執行一次,一整天就不用看盤了,覺得是蠻實戰的,可以參考看看。
筆者 Sean
奈米戶投資人 / Python愛用者
喜歡用Python玩轉金融數據,從個股基本面、技術面、籌碼面相關資料,一直到總體經濟數據,都是平常接觸到的素材;對於投資,除了研究歷史數據,也喜歡瞭解市場上大家在玩些什麼。