「垃圾進,垃圾出」

photo by Unsplash

前言

有在接觸量化投資的大家想必都對公開數據源相當熟悉(像是Yahoo Finance,Google Finance…..),經常在回測時被大家拿來使用,但是許多公開數據源並非台灣的資料庫公司,相較於美國市場,台灣市場在資料維護上並不完善,而回測的資料本身有缺陷下,就可能使模型或策略之績效失真。此時便凸顯出資料品質的重要性,但要如何針對資料品質進行確認呢? 本集我們將帶領大家來一探究竟~

本文重點概要

  • 調整股價與未調整股價 介紹/使用
  • 免費資料 vs TEJ API 資料品質的差異

未調整股價 vs 調整股價

假設0050在10年前30元,當前股價為120元,乍看之下投資報酬率為300%,但此情況卻未考慮到現金股利的發放,故並不是那麼貼近真實報酬率。用未調整股價進行計算,相當於忽略了股利發放的部分,但對存股族來說他們就是要賺殖利率,這樣的計算方式確實不夠精確。

調整股價變動是考慮了現金股利/股票股利/現金增資等影響,還原出來的價格,假設0050在10年前的還原價格為10元,現在的還原價格為100元,總共上漲了900%,由此案例便可發現,以調整後股價所算出的實際投資報酬率會比只考慮價差的投資報酬率來得更準確、優渥!

個股要考慮的因素比 ETF 來的多,往後將提供更全面的介紹,若想知道更多請 Follow 我們,並持續關注我們的文章~

  • 未調整股價 ➡️ 市價
  • 調整後股價 ➡️ 還原現金股利/股票股利/現金增資後的價格

下面我們將以 0050 為例,檢驗調整與未調整股價計算出的報酬率差異

匯入套件

如果還沒有api_key的話,可以在TEJ API官網上🆓免費註冊試用版🆓,不過要注意的是,試用能取得的資料範圍有所限制噢 ❗️ 本次使用的資料為斜槓方案的證券交易資料表 (TWN/EWPRCD),若想更自由的使用資料的話可以參考 TEJ E Shop🎁

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader as pdr
import tejapi
tejapi.ApiConfig.api_key = 'your key'

自 TEJ 撈取調整與未調整股價

stk_num = '0050'
stk_data = tejapi.get('TWN/EWPRCD',coid = stk_num,paginate = True
                      ,opts= {'columns':['coid','mdate','open_d','high_d','low_d','close_d']}) 
# 未調整股價
stk_adj = tejapi.get('TWN/EWPRCD',coid = stk_num,paginate = True
                    ,opts= {'columns':['coid','mdate','open_adj','high_adj','low_adj','close_adj']}) 
# 調整後股價
未調整
調整後

資料視覺化

plt.style.use('seaborn')
plt.figure(figsize=(10,5))
plt.title('0050',fontsize = 20)
l1 = plt.plot(stk_data.mdate,stk_data.close_d,label = 'market_price')
l2 = plt.plot(stk_adj.mdate,stk_adj.close_adj,label = 'adjusted_price')
params = {'legend.fontsize': 14,
          'legend.handlelength': 3,
         'axes.labelsize': 25}
plt.rcParams.update(params)
plt.legend(loc="upper left")
plt.xlabel('Date', fontsize=20)
plt.ylabel('Price', fontsize=20)
plt.show()

報酬率檢視

報酬率計算方式:以資料起始日當天收盤價為買進價格(buy_price),資料最近一日收盤價為賣出價格(sell_price),報酬率為 (賣出價格 – 買進價格)/買進價格,結果發現調整股價與未調整股價,兩者報酬率差異超過 40%。

 

# 調整後和未調整股價 報酬率差異
buy_price_mp, buy_price_adj = stk_data.close_d.values[0], stk_adj.close_adj.values[0]
sell_price_mp, sell_price_adj = stk_data.close_d.values[-1], stk_adj.close_adj.values[-1]
return_mp, return_adj = ((sell_price_mp-buy_price_mp)/buy_price_mp), ((sell_price_adj-buy_price_adj)/buy_price_adj)
print("未調整股價報酬率:",return_mp,"調整股價報酬率:", return_adj)

免費資料 vs TEJ API

除了TEJ 有計算調整股價外,免費資料源(本次採用的為Yahoo Finance的API)也同樣有提供調整後收盤,故我們要對兩者的調整後收盤進行比較。

匯入套件

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader as pdr
import tejapi
tejapi.ApiConfig.api_key = 'your key'

撈取資料

stk_num = '0050'

stk_adj = tejapi.get('TWN/EWPRCD',coid = stk_num,paginate = True
                    ,opts= {'columns':['coid','mdate','open_adj','high_adj','low_adj','close_adj']}) 
# 調整後股價
yf_data = pdr.DataReader(stk_num+'.tw','yahoo') # Yahoo Finance股價
TEJ 調整收盤
YF 調整收盤

資料視覺化

plt.style.use('seaborn')
plt.figure(figsize=(10,5))
plt.title('0050',fontsize = 20)
l1 = plt.plot(yf_data.index,yf_data['Adj Close'],label = 'yf_adjusted')
l2 = plt.plot(stk_adj.mdate,stk_adj.close_adj,label = 'tej_adjusted')
params = {'legend.fontsize': 14,
          'legend.handlelength': 3,
         'axes.labelsize': 25}
plt.rcParams.update(params)
plt.legend(loc="upper left")
plt.xlabel('Date', fontsize=20)
plt.ylabel('Price', fontsize=20)
plt.show()

由於斜槓方案有資料期間5年的限制,因此資料長度的差異不夠明顯,我們再進一步呼叫TEJ的原始資料庫便能夠發現:

❗️❗️ yf 的資料自2016年附近開始,但TEJ 早在2004年前就已有資料 ❗️❗️

若需要較長時間年度的資料的話,請與我們聯繫

TEJ 資料庫

根據證交所的公開資訊顯示台灣50的上市日期為2003年6月30日,這時候就能發現資料品質的重要性。

台灣50(0050)基本資料

報酬率檢視

報酬率計算方式:以資料起始日當天調整收盤價為買進價格(buy_price),資料最近一日調整收盤價為賣出價格(sell_price),報酬率為 (賣出價格 -買進價格)/買進價格 。

# yf調整後收盤和 tej調整後收盤 報酬率差異
buy_price_yf, buy_price_adj = yf_data['Adj Close'].values[0], stk_adj.close_adj.values[0]
sell_price_yf, sell_price_adj = yf_data['Adj Close'].values[-1], stk_adj.close_adj.values[-1]
return_yf, return_adj = (sell_price_yf-buy_price_yf)/buy_price_yf, (sell_price_adj-buy_price_adj)/buy_price_adj
print("yf調整後收盤報酬率:",return_yf,"tej調整後收盤報酬率:", return_adj)

資料品質

  • 資料起始日
  • 調整報酬率的差異

* 檢測 0050 成分股,免費資料與 TEJ 資料起始日期的差異

– start_date_tej :TEJ 資料的起始日期
– end_date_tej :TEJ 資料的最近一個交易日

– start_date_yf :免費資料的起始日期
– end_date_yf :免費資料的最近一個交易日

根據 公開資訊觀測站的資料顯示,台灣高鐵和永豐金的上市日期分別為 2016/10/27 、2002/05/09 ,與start_date_tej一致,可說明TEJ 在資料品質上是較佳的,故在回測時使用TEJ的資料較不會出現買進尚未上市的股票,出現回測績效失真的現象。

高鐵
永豐金

* 檢測 0050 成分股,YF 與 TEJ 調整後報酬率的差異

– ret_yf 為使用免費資料計算出的報酬率

– ret_tej為使用TEJ資料計算出的報酬率

計算方式:

– ret_yf = (end_date_yf 當日的調整後收盤價 – start_date_yf 當日的調整後收盤價)/start_date_yf 當日的調整後收盤價

– ret_tej= (end_date_tej 當日的調整後收盤價 — start_date_tej 當日的調整後收盤價)/start_date_tej 當日的調整後收盤價

difference 計算公式 : abs【(ret_yf – ret_tej)/ret_tej 】

以排序前10名為例

結語

這次分享給大家的是調整股價與未調整股價之簡略差異,往後我們將提供更詳的介紹,再來是免費數據與付費資料(TEJ API)的比較,從資料長度和報酬率來看,免費API 的資料品質確實較不穩定(免費的最貴 😂資料品質不穩固的情況下更為模型/策略增添額外的變數,推薦大家在進行回測時要使用品質更加穩固的資料源喔~

此外,我們在未來還會分享更多python的金融資料分析實作,如果有想知道的內容或感興趣主題可以在下方留言告訴我們 ❗️❗️

最後,如果喜歡本篇文章的內容請幫我們點擊下方圖示👏 ,給予我們更多支持與鼓勵,有任何的問題都歡迎在下方留言/來信,我們會盡快回覆大家👍👍

完整程式碼

延伸閱讀

相關網站連結

🌟有任何使用上的問題都歡迎與我們聯繫:聯絡資訊🌟

想看更多內容?快來【登入會員】,享受更多閱讀文章的權限喔!
返回總覽頁