【實戰應用】羅傑.金(Roger E. King)的投資策略
透過Python實測羅傑.金的選股法則
* 前言 — 羅傑.金是誰?
羅傑‧金(Roger E. King)是美國知名的價值型基金經理人,曾任職太陽保險服務公司(Sun Insurance Services)的資深副總裁兼投資長及葛夫科資本管理公司(GULFCO Investment Management)的資深副總裁,1981年創立國王投資顧問公司(King Investment Advisors Inc.),至2001年,投資經歷長達30年。
原本國王投資顧問公司只管理機構投資者的資金與個人退休基金,1996年底才發行第一檔股票共同基金-源頭特別價值基金(Fountainhead Special Value Fund),1997年即一鳴驚人,獲得36.65%的投資報酬率,1999年投資報酬率達133.44%,2000年雖股市表現不佳,但基金績效只損失15.71%,至2001年5月止,3年平均報酬率達18.22%,超越同期S&P500指數表現12.92個百分點,因此獲得晨星公司(Morningstar Co.)基金評等5顆星的評價,投資績效表現非常優異。
他自行研發一種稱為『企業評價方法(Business Valuation Approach)』的選股策略,以由下而上(bottom up)的選股方式為主,分為三種價值評估方式:
(一)私有市場評價(Private-market Valuation,Liquidation or acquired in a cash transaction);
(二)歷史評價(Historical Valuation);
(三)優越的盈餘成長(Superior Earning Growth,Buy growth at a reduced price:GARP)
三種方法所選出的公司皆可為投資標的,再以財務強度及內部人進出等指標進行篩選;雖然羅傑‧金被市場定位為價值型投資者,但他強調並不排斥買進具有投資價值的成長股,他在接受媒體專訪時曾表示『投資成功的秘訣在於買到便宜的價格(The secret of success is to buy at an inexpensive price),本次介紹的是第二種選股方法「歷史評價」。
✨本文重點概要 ✨
- 大師策略/ 調整後的策略 介紹
- 調整後策略績效展示
🚪本次使用的相關網站連結🚪
- 1️⃣ API官方網站:TEJ API 官網
- 2️⃣本文範例產品包:TEJ E SHOP
- 3️⃣本文完整程式:TEJ GITHUB
* 羅傑.金 👑
選股程序及標準:以七年歷史資料為期,計算以下指標的狀況,判斷目前股價上漲空間(Potential Upside)及下檔風險(Potential Downside)。
歷史最高本益比平均及最低本益比平均。
歷史最高股價淨值比平均及最低股價淨值比平均。
歷史最高股價現金流量比平均及最低股價現金流量比平均。
歷史最高股價營收比平均及最低股價營收比平均。
堅強的財務狀況。
內部人進出的狀況。
從上面指標選擇的項目可以看到,羅傑‧金先找出每年的當年度本益比最大值與最小值,然後分別取平均值,計算出選股時點本益比的上下限;接著納入股價淨值比、現金流量、營收等基本面常見指標,以相同的方式計算出各指標與股價間比例的上下限。藉由多個基本面指標設算出的股價的上下檔目標價,並且以目前股價較接近上檔目標價或下檔目標價,來判斷是否該買入此股票。
⬇️ 因應時空背景的轉換,我們對上列條件進行了調整與修正⬇️
* 調整後策略
使用方法:
選股程序及標準:選定歷史資料使用年數為7年。
運算過程:
歷史本益比上檔目標價=最近7個年度最高本益比平均值x最近一季每股盈餘。
歷史本益比下檔目標價=最近7個年度最低本益比平均值x最近一季每股盈餘。
歷史股價淨值比上檔目標價=最近7個年度最高股價淨值比平均值x最近一季每股淨值。
歷史股價淨值比下檔目標價=最近7個年度最低股價淨值比平均值x最近一季每股淨值。
歷史股價現金流量比上檔目標價=最近7個年度最高股價現金流量比平均值x最近四季每股現金流量。
歷史股價現金流量比下檔目標價=最近7個年度最低股價現金流量比平均值x最近四季每股現金流量。
歷史股價營收比上檔目標價=最近7個年度最高股價營收比平均值x最近12個月每股營收總額。
歷史股價營收比下檔目標價=最近7個年度最低股價營收比平均值x最近12個月每股營收總額。
選股標準:
以下四個選股標準,即是計算當前股價,是否較接近該指標所算出的下檔目標價,較接近者就代表價格偏移長期行情的中間值,值得買入。
歷史本益比報酬/風險值=[(歷史本益比上檔目標價-目前股價)/目前股價]/ [(目前股價-歷史本益比下檔目標價)/目前股價]>1。
歷史股價淨值比報酬/風險值=[(歷史股價淨值比上檔目標價-目前股價)/目前股價]/ [ (目前股價-歷史股價淨值比下檔目標價)/目前股價]>1。
歷史股價現金流量比報酬/風險值=[(歷史股價現金流量比上檔目標價-目前股價)/目前股價]/ [ (目前股價-歷史股價現金流量比下檔目標價)/目前股價]>1。
歷史股價營收比報酬/風險值=[(歷史股價營收比上檔目標價-目前股價)/目前股價]/[ (目前股價-歷史股價營收比下檔目標價)/目前股價]>1。
以上4項指標,符合1項即為選股標的。再以下面條件過濾篩選:
剃除選股時間點近一季負債比率大於65%的公司。
按照羅傑金的選股標準「歷史本益比報酬/風險值」,其實計算的就是股價距離下檔目標價的距離,是否比距離上檔目標價來的短,也就是股價目前按照長期均勢的本益比來看,是否偏低,若是,就可以買進。
* Python實作 💻
- 資料收集/資料整併
- 篩選股票
- 回測績效
- 績效視覺化
1️⃣ 資料收集/資料整併
匯入套件 🎁
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn')
import tejapi
tejapi.ApiConfig.api_key = 'your_key'
tejapi.ApiConfig.ignoretz = True
撈取財務數據 👷
- 自證券屬性資料表(TWN/ANPRCSTD)得到所有證券代碼,並篩選出上市普通股。
- IFRS以合併為主簡表(累計)-全產業 (TWN/AIM1A)撈取財務數據,如日期、每股淨值(F)、常續性EPS、負債比率、每股現金流量、每股營業額。
# 獲取上市普通股代碼 #
stk_info = tejapi.get('TWN/ANPRCSTD',
paginate=True,
chinese_column_name=True
)
stk_nums = stk_info[(stk_info['上市別']=='TSE') & (stk_info['證券種類名稱']=='普通股')]['證券碼'].to_list()
# 撈取財務資料 #
zz = pd.DataFrame()
for code in stk_nums:
zz = zz.append(
tejapi.get('TWN/AIM1A',
coid=code,
paginate=True,
chinese_column_name=True,
opts= {'pivot':True,'columns':['coid','mdate','200D','R535','R505','R303','R304','MV']}).reset_index(drop=True)
).reset_index(drop=True)
print(code)
👼 Tips : 如何搜尋想要的欄位代號,輸入關鍵字,並運行下方程式碼,即可找出相對應的欄位代號~
# IFRS財務會計科目說明檔 #
acc = tejapi.get(‘TWN/AIACC’,paginate=True)
# 搜尋欄位代碼 #
key_word = '輸入關鍵字'
acc[acc[‘cname’].str.find(key_word)!=-1]
資料整合 👷
2010年12月底的本益比(PE), 股價淨值比(PB), 股價現金流量(PC)和股價營收比(PS),由財報在發佈上有落後的情況,因此上述指標的運算皆使用2010-3-31至2011-3-31的股價資料進行計算。
下方程式碼功能為計算個年度本益比(PE), 股價淨值比(PB), 股價現金流量(PC)和股價營收比(PS)之最高和最低值。
⏰ PS. 由於資料量較大,程式運行時間也較久大約30~40分鐘
滾動平均 🏄
根據上面得到的結果針對本益比(PE), 股價淨值比(PB), 股價現金流量(PC)和股價營收比(PS)進行7年移動平均計算,並將當期的EPS、每股淨值、每股現金流量和每股營收合併,即可得出當前的最高目標價和最低目標價。最後再進一步求算出風險報酬比。
mean_7 = results.groupby(by=['公司代碼']).rolling(7).mean()[['PE_max','PE_min','PB_max','PB_min','PC_max','PC_min','PS_max','PS_min']]
mean_7 = mean_7.reset_index(drop=True)
mean_7['year'],mean_7['公司代碼'],mean_7['stk_start_price'] = results['year'], results['公司代碼'],results['stk_start_price']
# 合併 #
mean_7 = pd.merge(mean_7.dropna(),data,on=['公司代碼','year'])
# 去除市值小於中位數者 #
mean_7 = mean_7[(mean_7['季底普通股市值']>mean_7['mv_median'])].reset_index(drop=True)
2️⃣ 篩選股票
篩選條件:
歷史本益比報酬/風險值=[(歷史本益比上檔目標價-目前股價)/目前股價]/ [(目前股價-歷史本益比下檔目標價)/目前股價]>1。
歷史股價淨值比報酬/風險值=[(歷史股價淨值比上檔目標價-目前股價)/目前股價]/ [ (目前股價-歷史股價淨值比下檔目標價)/目前股價]>1。
歷史股價現金流量比報酬/風險值=[(歷史股價現金流量比上檔目標價-目前股價)/目前股價]/ [ (目前股價-歷史股價現金流量比下檔目標價)/目前股價]>1。
歷史股價營收比報酬/風險值=[(歷史股價營收比上檔目標價-目前股價)/目前股價]/[ (目前股價-歷史股價營收比下檔目標價)/目前股價]>1。
以上4項指標,符合1項即為選股標的。再以下面條件過濾篩選:
剃除選股時間點近一季負債比率大於65%的公司。
Backtest 📈
- If one of four conditions is met, we will buy the stock.
- Rebalancing portfolio per.
- Equally weighted.
- The benchmark is twse.
- The buy date is t+90, holding period is one year, and the sell date is one year after the buy date.
累積報酬 🏰
cum_ret = return_[['portfolio','twse_return']].astype(float).apply(lambda x:x*0.01+1).cumprod().reset_index(drop=True)
cum_ret['Date'] = return_['Date']
cum_ret
績效視覺化 📊
累積報酬折線圖
cum_ret.plot(x='Date',figsize=(10,6))
績效指標/報表 📈
# 績效報表 #
yearly_mean_ret = (((cum_ret[['portfolio','twse_return']].tail(1)**(1/len(cum_ret)))**252-1)*100).reset_index(drop=True)
yearly_std = cum_ret[['portfolio','twse_return']].std()*(252**(0.5))
Rf = 1
sp_ratio = (yearly_mean_ret-Rf)/yearly_std
roll_max = cum_ret[['portfolio','twse_return']].cummax()
draw_down = (cum_ret[['portfolio','twse_return']]-roll_max)/roll_max
MDD = draw_down.min()*100
performace_report = pd.DataFrame({
'portfolio':[yearly_mean_ret['portfolio'].values[0],
yearly_std['portfolio'],
sp_ratio['portfolio'].values[0],
MDD['portfolio']],
'twse_return':[yearly_mean_ret['twse_return'].values[0],
yearly_std['twse_return'],
sp_ratio['twse_return'].values[0],
MDD['twse_return']]}
,index= ['年化報酬','年化波動度','夏普指標','最大回檔'])
performace_report
最新一期的投資組合 ✅
pf2020 = mean_7[(mean_7['year']==2020) & (mean_7['負債比率'] < 65) & (mean_7['score']>=1)]['公司代碼'].to_list()
stk_info[['證券碼','證券名稱']][stk_info['證券碼'].isin(pf2020)].reset_index(drop=True)
總結
由報酬率來看,我們的投資組合確實勝過大盤指數,但將風險納入考慮之後,可以看出台灣加權指數分別在波動度、夏普指標和最大回檔皆勝過我們的投資組合😢😢。
這次的羅傑.金的策略在報酬上只有險勝大盤指數一點,是不是相當意外阿~不過,會出現這樣的結果也不必太過驚訝,畢竟投資領域上並無一個長期穩定的聖杯,所有的條件都應該隨著時間進行動態調整 👍👍
重要的是我們如何從這些過往的投資大師身上汲取經驗和刺激想法,最後經過自己的一番練化,去蕪存菁,建構出適合自己的投資策略😄,
我們將在下期繼續分享三一資產管理公司的投資策略,敬請期待!!
最後,如果喜歡本篇文章的內容請幫我們點擊下方圖示👏 ,給予我們更多支持與鼓勵,有任何的問題都歡迎在下方留言/來信,我們會盡快回覆大家👍👍
想要一個"穩定""品質高""資料長度長"的資料源該怎麼辦呢?TEJ API就是你最好的選擇!!
再次附上相關網站連結 💪
- API官方網站:TEJ API 官網
- 本文範例產品包:TEJ E SHOP
- 本文完整程式:TEJ GITHUB
🌟有任何使用上的問題都歡迎與我們聯繫:聯絡資訊🌟
附上完整程式碼 🚪