本益比選股策略 | 產業因子分析

本益比指標(Price-to-Earning Ratio 簡稱:PE)因概念非常直覺,是大家耳熟能詳的評價指標,這篇文章會帶大家來驗證本益比指標的相關策略,示範如何使用使用Finlab量化平台工具幫助開發,說明策略撰寫的脈絡,進而延伸到結合產業因子的進階策略。

開發環境安裝

首先安裝最新版本的finlab套件:

pip install finlab

再引入接下來會使用的套件準備開發:

from finlab import data
from finlab.backtest import sim
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
import plotly.figure_factory as ff

本益比定義

這篇文章使用的是來自證交所櫃買中心每日的本益比資料,本益比計算方式如下:

本益比 (倍) = 當前股價(Price) / 近四季每股稅後盈餘(EPS)

例如公司A股價10元,而過去四季的每股盈餘EPS是1元,
每股稅後盈餘( 簡稱EPS)意思是你手上的每1股股票今年賺了多少錢。

本益比 = 股價10元/每年賺1元 = 10倍,換句話說,若獲利能力保持,需要10年才能回本。數字越小代表預期回本時間越少,數字越大代表預期回本時間越多。

PE單因子回測

PE真的是越低越好嗎?會不會PE評價高的標地更會飆?利用finlab.data.sim我們可以輕鬆的回測我們的想法。

全市場PE區間倍率回測

我們以PE間隔5倍分別回測,ex:0-5倍、5-10倍…、40-45倍、50-1000倍(高本益比區間)。設定每月初換股一次,持有PE於區間內的標的。

撰寫以下回測程式,並製作plotly視覺化使用的dataframe。

def get_pe_return():
    # 下載本益比資料
    pe = data.get('price_earning_ratio:本益比')

    # 設定測試區間(最後測試 PE = 50 ~ 1000)
    test_range = list(np.arange(0,55,5)) + [1000]

    # 回測序列資料集
    return_dataset = {}

    for start, end in zip(test_range, test_range[1:]):

        # 選股條件
        position = (pe > start) & (pe < end)

        # 進行回測,upload設為false,不上傳資料到平台,加快回測
        report = sim(position=position, resample='M', upload=False)

        # 製作繪圖dataframe
        return_dataset[f"{start}-{end}"] = report.creturn

    return_dataset = pd.DataFrame(return_dataset)
    return return_dataset

return_dataset = get_pe_return()

接著將dataframe導入plotly.express。

fig = px.line(return_dataset, title='pe multiple backtest')
fig.show()

fig = px.bar(return_dataset.iloc[-1], color=return_dataset.iloc[-1].values, title='pe multiple backtest bar')
fig.show()

由圖可知,PE區間10-15倍最好,大致呈現單調線性關係,PE越低的報酬率越好,但極高PE的區間的報酬率又再度高起,代表有不少高本益比的標的報酬率也不錯,顯示PE指標的趨勢分隔性可能不是太優。

全市場策略範例

我們將表現最好的10-15倍區間寫成策略,並上傳量化平台。

pe = data.get('price_earning_ratio:本益比')
position = (pe>10) & (pe<15)
report=sim(position=position,resample='M',name="策略教學範例:pe_single_factor",upload=True)
report.benchmark = data.get('benchmark_return:發行量加權股價報酬指數').squeeze()

可以發現報酬率相當貼近大盤,推測很難使用PE單因子策略打敗大盤,我們要進一步去思考PE評價模式適合用於每一個產業嗎?例如某些產業如半導體的市場評價較高,低倍本益比可能不適用。市場上常說景氣循環股獲利高峰常見本益比低點,成長延續性差,如鋼鐵航運族群要把本益比反著看,真的是如此嗎?接下來我們可以思索其他變因去優化,嘗試加入產業因子去分析。

產業PE回測

我們使用data.set_universe(category='產業名')來設定回測的產業範圍,帶入先前的回測程式得出各產業最終報酬率的熱力圖,方便觀察數據。

由熱力圖顏色深淺,可知每一個產業在不同PE區間的報酬率序列變化。若該產業適用於PE評價,報酬率應該要與PE倍數呈現線性關係,顏色應呈現漸層變化。

若規律跳動混亂,如其他、化工、電子通路族群,就不太適合套用PE評價。

若50-1000倍的報酬率在該產業的前幾名,如半導體、鋼鐵、電腦週邊,代表不太適合用低PE去抓潛在高報酬標的,該產業可能較多轉機飆股的整體PE評價偏高。

我們可以將各產業於PE 10-15倍區間依大小排列,取前5高報酬率的產業&PE v.s.報酬率變化呈現線性關係的產業做產業因子範圍,分別是 ‘食品工業’,’紡織纖維’,’航運業’,’油電燃氣業’,’橡膠工業’,都是傳統產業,本益比評價較科技業低,符合傳統假設,但景氣循環股不適用的假設和回測結果不同。

PE&產業因子策略範例

接著將產業因子加入回測。

category = ['食品工業','紡織纖維','航運業','油電燃氣業','橡膠工業']
data.set_universe(category=category)
pe = data.get('price_earning_ratio:本益比')
cond1= (pe>10) & (pe<15)
position=cond1
ind_report=sim(position=position,resample='M',name="策略教學範例:pe_industry_factor",upload=True)
data.universe_stocks = set()
ind_report.benchmark = data.get('benchmark_return:發行量加權股價報酬指數').squeeze()

策略比較

回測比較可以發現加入產業因子後,各項數據都較使用全市場標的有明顯的優化,年化報酬上升到21%,拉開與大盤的差距,只有2011年產生小幅虧損。

每一期的標地數介於10-40檔左右,無過少標地數影響報酬率的情況。

利用回測物件下的function:creturn.calc_stats().return_table獲取報酬率資料。在近12年度中,有2/3的年度優於未加入產業因子的情況,且輸都是小輸、贏都是大贏,並沒有勝率不穩定的情況。

還有沒有再優化的可能呢?加入其他財務或技術指標再限縮標地或停損停利來優化,就留給各位去發展了。

總結

PE無法做單因子選股去獨撐大樑,但確實是有用的因子,若加上其他條件相輔相成,有機會開發出不錯的策略,再開發其他策略時可以考慮加上PE去優化,如果是針對文中提到的特定產業的,可能有機會大大提升。

PE最為人詬病的地方就在於使用過去的獲利去評價,沒考量到未來的成長性會造成獲利得改變,下一篇會介紹本益成長比(簡稱:PEG)做更進階的應用。

對本篇程式有興趣的可以參考文底連結附檔,記得要先註冊Finlab量化平台才可有權限使用程式喔!

colab程式範例

喜歡我們的文章的話,那更別錯過我們精心製作的優質系列課程喔!

上一篇
下一篇

Genie

Python elf, love magic of python. Explore the financial world.