產業資料庫的基礎應用

  • Post author:
  • Reading time:5 mins read

產業資料庫重要嗎?如果你想讓選股技巧更上一層樓,勢必會進階到產業分析。
投資標的的優劣評價,除了自己跟自己比,例如近期財報是否較過去改善,另一個判斷企業競爭力的評價方式,就是跟同業比,好壞都是比較而來的,選對比較基準才讓評價有意義。
除了同業個股比較,產業資料庫的另一個主要應用在找出族群趨勢,如果一個產業的企業的營收或股價趨勢都向上,那代表該產業蒸蒸日上,有產業景氣良好的基本面護體,更能增加投資判斷把握度與可解釋性,排除單一個股炒作的個別性,更進階的應用甚至可延伸到概念股落後補漲效應。
這一切的應用的基礎都建構在「產業資料庫」的分類,這篇教學文章將說明FinLab的「產業題材資料庫」的簡單應用,並教你如何用 Python 與 Pandas 基礎語法去「客製化」自己的產業分類,讓產業資料庫更豐富。

產業資料

FinLab 的細產業主題資料來源主要取自「產業價值鍊資訊平台」,少部分為自定義分類。從 FinLab資料庫 只要一行程式碼就能下載全部的細產業資訊,讓你輕鬆以此基礎做後續應用。要注意的是此份資料僅限 VIP 使用。
產業價值鍊資訊平台 會將主產業再分拆上下游的細產業,讓你更精細的去比較,否則證交所一般分類光半導體就近百檔,比較效果相對籠統。

截圖 2022 11 02 上午7.30.52
資料庫欄位

每家公司所屬產業的資訊放在 catergory 內,category 欄位的型態是文字格式,所有產業分類會放入 List 後再包成文字型態,從該資料得知公司分別有哪些產業的標籤。
例如1101台泥的產業序列裡有主產業的水泥,也有細產業「水泥:水泥成品」、「水泥:水泥熟料」(格式為「主產業:細產業 or 主產業」)。

截圖 2022 11 02 上午7.35.04

簡單查詢應用

如果我們想查詢哪些公司屬於水泥產業?我們可以運用pandas內的 Series.str.contains,讓我們快速分類出產業名單,如下範例,只要「category」欄位內含「水泥」兩字,就會被納入範圍。

from finlab import data
from finlab.backtest import sim

# 取出產業題材
themes = data.get('security_industry_themes')

# 選出產業包含「水泥」的公司
ind1 = themes[themes['category'].str.contains('水泥')]
截圖 2022 12 20 下午12.36.55

contains 語法支援 or 的運用,如果我們今天想選出產業包含「水泥」或「建材營造」的公司,可以使用以下語句,使用’|’的符號做邏輯運算串連:

ind2 = themes[themes['category'].str.contains('水泥|建材營造')]

截圖 2022 12 20 下午12.37.48

簡單回測範例

「想挑出水泥產業中,本益比低於水泥產業本益比中位數之個股當投資組合」

實作很簡單,用前述contains篩選的stock_id,套入本益比資料做欄位圈選,就能限定資料範圍,再運用 median(axis=1),計算每日產業本益比中位數,axis=1的用途在取每一期(橫列)的中位數。

from finlab import data
from finlab.backtest import sim

# 取出產業題材
themes = data.get('security_industry_themes')

# 選出產業包含「水泥」公司
ind = themes[themes['category'].str.contains('水泥')]
pe = data.get('price_earning_ratio:本益比')
ind_pe = pe[list(ind['stock_id'])]

# 計算每日產業本益比中位數,axis=1的用途在取每一期(橫列)的中位數
ind_pe_med = ind_pe.median(axis=1)

# 選出本益比小於同業本益比中位數且本益比小於25的公司
position = (ind_pe < ind_pe_med) & (ind_pe < 25)

# 回測
report = sim(position, upload=False)
report.display()
newplot 2

自定義產業分類

有時我們發現產業價值鏈資訊平台的分類仍不能滿足需求,像是他缺少概念股的標籤資料,學會Python 的好處在我們可以任意擴展資料,去自定義新增的分類。
使用開發好的 create_new_industry_themes 的函式去創建新的產業分類,其中 additional_themes 變數控制新增標籤,格式為[([目標群],[標籤群]),...]

例如以下範例對’6684′, ‘6756’, ‘3014’ 新增 ‘元宇宙:祖克柏概念股’ 的標籤,對’1342′, ‘1584’新增’航太週邊:空中巴士概念股’的標籤,對’2342′, ‘3317’, ‘4923’, ‘5299’, ‘6287’ 增加兩個標籤’半導體:基礎元件’, ‘通訊產業:通訊元件’。

def add_sub_group(dataframe, stock_list: list, theme_list: list):
    try:
        dataframe.loc[stock_list]['category'] = dataframe.loc[stock_list]['category'].apply(
            lambda s: s.extend(theme_list))
    except KeyError:
        print('stock_list not in index.')
    return dataframe


def process_sub_group_list(sub_group_list):
    sub_group_list.extend(list(set({i[:i.index(':')] for i in sub_group_list if ':' in i})))
    return sorted(list(set(sub_group_list)))


def create_new_industry_themes(additional_themes):

    df = data.get('security_industry_themes')
    df = df.set_index(['stock_id', 'name'])
    df['category'] = df['category'].apply(lambda s: eval(s))

    if additional_themes:
        for stock_list, theme_list in additional_themes:
            df = add_sub_group(df, stock_list, theme_list)

    df['category'] = df['category'].apply(lambda s: process_sub_group_list(s))
    df = df.astype(str)
    df = df.reset_index()
    return df


additional_themes = [
    (['6684', '6756', '3014'], ['元宇宙:祖克柏概念股']),
    (['1342', '1584'], ['航太週邊:空中巴士概念股']),
    (['2342', '3317', '4923', '5299', '6287'], ['半導體:基礎元件', '通訊產業:通訊元件']),
]


new_themes = create_new_industry_themes(additional_themes)
# 檢查6684 是否成功新增標籤
new_themes[new_themes['stock_id']=='6684']['category'].values



截圖 2022 12 20 下午2.02.42

執行完含式後,會發現 new_themes 已有新增資料~之後就可以用自定義後的 new_themes 做產業分析囉!

小結

colab程式範例

學會基礎的產業資料的資料處理技巧後,就可以進行許多分析與策略開發,像是「產業面選股策略|同業本益比比較法」就是延伸的應用喔!
如果有自己的產業分類標籤可以加入,那就會進化成個人獨有的資料,可能創造出不易被模仿的策略或產業觀察指標。

Ben

Python 軟體工程師與量化策略研究員。 鑽研資料工程、網頁後端、資料視覺化、量化交易策略開發。 投資主力在台股市場,量化策略為主、質化分析為輔,追求人機攜做最佳化。逐步將觸角延伸到總經、美股、加密貨幣,朝更全方位的交易人邁進。