文件
開啟 Studio

教學

技術指標

本頁內容7

data.indicator() 支援 TA-Lib 與 pandas_ta 上百種技術指標,一行就算出數千檔股票、長年期的結果,可用於個股分析與機器學習。結果和 data.get() 一樣是「日期 × 股票」的表,可以直接拿來寫選股條件。

安裝 TA-Lib

!pip install ta-lib

更多參數與函式請參考 TA-Lib 官方文件。

計算所有股票的 RSI

把指標名稱和參數交給 data.indicator(),例如 RSI(timeperiod=14):

from finlab import data

data.indicator('RSI', timeperiod=14)
data.indicator 計算全部股票 RSI 的結果 DataFrame
  • 會計算目前市場的所有股票,每一列是日期、每一欄是股票代號。
  • 前 14 天因資料不足可能為 NaN。
  • 預設用未還原股價計算;adjust_price=True 改用還原股價,resample='W' 改用週 K。

計算兩條線的指標:KD

data.indicator('STOCH') 計算 KD 值,會回傳兩個 DataFrame(K、D):

from finlab import data

k, d = data.indicator('STOCH')
k
data.indicator 計算 KD 值回傳的 K 值 DataFrame

挑出 K 值大於 D 值的股票

(k > d).iloc[-1] 取最近一日的結果,是一個以股票代號為索引的布林 Series:

(k > d).iloc[-1]
0015    False
0050     True
0051    False
0052     True
0053     True
        ...
9951     True
9955    False
9958    False
9960     True
9962     True
Name: 2021-07-13 00:00:00, Length: 2269, dtype: bool

只要 K 大於 D 的股票代號:

signal = (k > d).iloc[-1]
signal[signal].index  # 最近一日 K 大於 D 的股票代號

用 pandas_ta 算更多指標

pandas_ta 也能計算多種技術指標,安裝方式與指標列表請見官方文件:

pip install pandas-ta

一樣透過 data.indicator() 使用,例如 supertrend:

from finlab import data

values = data.indicator('supertrend')

若 TA-Lib 沒有對應的函式,會改用 pandas_ta 計算(可能較慢)。

用 Pandas 自製指標

不依賴 TA-Lib,直接用 Pandas 運算建立自訂指標。

動能、乖離率與營收成長

from finlab import data

close = data.get('price:收盤價')
volume = data.get('price:成交股數')
rev = data.get('monthly_revenue:當月營收')

# 動能指標:N 日報酬率
momentum_20 = close / close.shift(20) - 1

# 均線乖離率
ma60 = close.average(60)
bias = (close - ma60) / ma60

# 量價背離:股價創高但成交量萎縮
price_high = close == close.rolling(60).max()
volume_low = volume < volume.average(20)
divergence = price_high & volume_low

# 月營收成長率
rev_yoy = rev / rev.shift(12) - 1  # 年增率
rev_mom = rev / rev.shift(1) - 1  # 月增率
rev_3m = rev.average(3) / rev.average(12) - 1  # 3 月均值 vs 12 月均值

合成多因子分數(.cs)

.cs 在每個日期跨所有股票計算。先把每個因子標準化,再等權加總:

pe = data.get('price_earning_ratio:本益比')
roe = data.get('fundamental_features:ROE稅後')

# 多因子合成:先標準化再等權加總
score = roe.cs.zscore() + (-pe).cs.zscore()  # ROE 越高越好,PE 越低越好

# 選出綜合評分前 10%
position = score.cs.rank() > 0.9

產業中性化(.sector)

直接用 ROE 選股,會偏重 ROE 本來就高的產業。改在產業內標準化,選出「在各自產業中表現突出」的股票:

# 問題:直接用 ROE 選股會偏重高 ROE 產業(如半導體)
# 解法:產業內標準化,選出「在各自產業中表現突出」的股票

roe_neutral = roe.sector.zscore()  # 產業中性化
rev_neutral = rev_yoy.sector.zscore()  # 營收成長也做中性化

# 合成因子
score = roe_neutral + rev_neutral
position = score.cs.rank() > 0.8

# 也可以直接用產業內排名
position = roe.sector.rank() > 0.7  # 各產業 ROE 前 30%

設定權重並回測(.weight)

選好股票後,用 .weight 決定每檔的權重,再交給 sim() 回測:

from finlab.backtest import sim

position = score.cs.rank() > 0.8

# 精細權重:反波動率 + 產業上限 + 換手率限制
weights = (
    position.weight.inverse_volatility(window=60)
    .weight.cap_industry(max_weight=0.3)
    .rebalance('QE')  # 只留換股日,換手率才是每次換股之間的
    .weight.limit_turnover(max_turnover=0.3)
)

report = sim(weights, resample='Q')

.cs、.sector、.weight 的所有方法詳見 finlab.dataframe 參考文件。

下一步

↑↓ 選擇 Enter 開啟 Esc 關閉