跳轉到

分析策略因子

研究因子分析,增減修改因子,不再靠感覺,瞭解因子與策略報酬的關係。

FinLab Package 提供的因子分析流程:

範例策略
    ├─── 特徵工程 ────→ 因子特徵 (Features)
    └─── 標籤工程 ────→ 超額報酬 (Labels)
                ├─── calc_factor_return() ────→ 因子報酬
                │      │
                |      └── calc_centrality() ─→ 因子集中度
                ├─── calc_shapley_values() ───→ 因子貢獻度
                └─── calc_ic() ───────────────→ 因子相關性(IC)

我們將示範將

  1. 「範例策略」轉換成「特徵」與「標籤」
  2. 用上述資料分析因子的效能

範例策略

此策略是由非常基本的三個因子組成: 1. 市值 2. 營收 3. 動能

from finlab import data
from finlab.backtest import sim

marketcap = data.get('etl:market_value')
revenue = data.get('monthly_revenue:當月營收')
price = data.get('etl:adj_close')

cond1 = marketcap.rank(pct=True, axis=1) < 0.3
cond2 = (revenue.average(3) / revenue.average(12)).rank(pct=True, axis=1) > 0.7
cond3 = (price / price.shift(20)).rank(pct=True, axis=1) > 0.7

pos = cond1 & cond2 & cond3

report = sim(pos, resample='ME', upload=False)
report.creturn.plot()

製作特徵與標籤

from finlab import data
import finlab.ml.feature as feature
import finlab.ml.label as label

features =  feature.combine({
    'marketcap': cond1,
    'revenue': cond2,
    'momentum': cond3
}, resample='ME')

# 計算未來 1M 的標籤
labels = label.excess_over_mean(index=features.index, resample='ME')

features.dropna().head()
datetime instrument marketcap revenue momentum
2013-04-30 1101 False True True
2013-04-30 1102 False True True
2013-04-30 1103 False True False
2013-04-30 1104 False True False
2013-04-30 1108 False True False
labels.dropna().head()
datetime    instrument
2007-04-30  1101          0.042548
            1102          0.081764
            1103         -0.016863
            1104         -0.047492
            1108         -0.002247
dtype: float64

因子報酬 (Factor Return)

因子報酬(Factor Return)是衡量某因子在一段時間內所帶來超額報酬的指標,常用於評估因子的有效性與投資價值。

在本分析流程中,會先根據不同的因子(如市值、營收成長、動能等)建立特徵,並計算每個因子的因子報酬。透過累積因子報酬的走勢,可以觀察該因子的長期表現與穩定性,進一步作為因子篩選與組合的重要依據。

下方將以圖表方式展示各因子的累積報酬表現。

from finlab.tools.factor_analysis import calc_factor_return
from finlab.plot import plot_line

plot_line(calc_factor_return(features, labels).cumsum(), unit='.0%', title='Factor Cumulative Return')

圖中,可以觀察月營收因子效果顯著比較好,但市值因子效果較差。

因子集中度(Factor Centrality)

因子集中度(Factor Centrality),是用來量化「共同性」的指標。

因子集中度(Centrality)定義如下:

\[ \text{Centrality}_i = \frac{\lambda_i}{ \sum_{j=1}^{k}\lambda_j} \]

其中,\(\lambda_j\) 為因子對於第一主成分的佔比,\(k\) 為因子總數。

此指標反映了因子報酬的共同性,

  • 數值越大表示
    • 利用此因子選股,在近期績效比較好。
    • 集中度越高,近而增加未來回檔的風險,需密切觀察。
  • 數值越小表示
    • 利用此因子選股,在近期績效較差。
    • 集中度越低,未來回檔的風險較低。
    • 可以在因子擁擠度較低的時候,密切觀察,等擁擠度上升初期,利用此因子選股。
from finlab.tools.factor_analysis import calc_centrality



plot_line(calc_centrality(calc_factor_return(features, labels), 12), title='Centrality')

上圖中,當市值因子目前擁擠度較低,可以換一個因子,讓策略更穩定。

另外,也可以密切觀察市值因子,等擁擠度上升初期,利用此因子選股(因子回歸效應)。

因子貢獻度(Shapley Values)

Shapley Values 是一種用於量化各個因子對投資組合報酬的貢獻度,是一種公平分配的數學方法。

我們枚舉所有可能的因子組合,計算每個因子組合的報酬,並計算每個因子對報酬的貢獻度。

我們甚至可以計算出,每個因子、每個時間點,對報酬的貢獻度。

值得一提的是,Shapley Values 的計算時間複雜度為 \(O(2^n)\),其中 \(n\) 為因子個數,因此計算時間較長,在因子個數較多時,建議使用其他方法。

from finlab.tools.factor_analysis import calc_shapley_values


plot_line(calc_shapley_values(features, labels))

因子相關性(Information Coefficient)

因子 IC(Information Coefficient)是衡量因子預測能力的重要指標,常用於評估因子與未來報酬之間的相關性。

IC 的計算公式如下:

\[ IC = \text{corr}(\text{Factor Score}, \text{Future Return}) \]

其中,\(\text{corr}\) 表示相關係數(通常為皮爾森相關),\(\text{Factor Score}\) 為因子分數,\(\text{Future Return}\) 為未來一段期間的資產報酬。

IC 數值範圍通常在 -1 到 1 之間:

  • IC 越接近 1,表示因子對未來報酬有很強的正向預測能力。
  • IC 越接近 -1,表示因子對未來報酬有很強的反向預測能力。
  • IC 接近 0,表示因子對未來報酬幾乎沒有預測能力。

在量化選股中,IC 是判斷因子有效性的重要依據,IC 越高的因子通常更值得納入投資組合。

from finlab.tools.factor_analysis import calc_ic

features =  feature.combine({
    'marketcap': -marketcap, # 小市值
    'revenue': revenue.average(3) / revenue.average(12),
    'momentum': price / price.shift(20)
}, resample='ME')

plot_line(calc_ic(features, labels, rank=True))

因子趨勢分析

概述

上述「集中度」「貢獻度」「相關性」隨時間變化數值,可以利用 calc_regression_stats 來計算趨勢:

from finlab.tools.factor_analysis import calc_regression_stats

centrality_df = calc_centrality(features, labels)
centrality_trend = calc_regression_stats(centrality_df)
slope p_value r_squared tail_estimate trend
marketcap -0.000111 3.102740e-17 0.404468 0.0123 down
revenue 0.000018 4.861743e-03 0.056041 0.0087 flat
momentum 0.000093 1.146515e-17 0.412914 0.0215 up

核心欄位

欄位 說明 數值範圍 含義
slope 線性回歸斜率 (-∞, +∞) 趨勢方向和強度
p_value 統計顯著性 [0, 1] 趨勢的可信度
r_squared 決定係數 [0, 1] 線性模型的解釋力
tail_estimate 尾部估計值 (-∞, +∞) 時間序列末端的預測值
trend 趨勢分類 "up"/"down"/"flat" 簡化的趨勢判斷

數值範圍與含義

slope (斜率)
  • 正值: 上升趨勢,擁擠度增加
  • 負值: 下降趨勢,擁擠度減少
  • 絕對值大小: 趨勢強度(越大越強)
p_value (統計顯著性)
  • [0, 0.01]: 極度顯著 (***)
  • [0.01, 0.05]: 高度顯著 (**)
  • [0.05, 0.1]: 邊際顯著 (*)
  • [0.1, 1]: 不顯著
r_squared (決定係數)
  • [0.8, 1.0]: 極強解釋力
  • [0.6, 0.8): 強解釋力
  • [0.4, 0.6): 中等解釋力
  • [0.2, 0.4): 弱解釋力
  • [0, 0.2): 很弱解釋力

趨勢組合分析

p_value r_squared slope trend 含義
up 強烈且穩定的上升趨勢
down 強烈且穩定的下降趨勢
任意 flat 趨勢存在但效果小/雜訊大
任意 flat 樣本少,雜訊高,無法判斷
任意 flat 基本無趨勢且模型無解釋力

實例分析

Marketcap (市值因子)
slope: -0.000111 (負值)
p_value: 3.10e-17 (極度顯著)
r_squared: 0.40 (中等偏強解釋力)
trend: down

解讀: 市值因子的集中度呈現非常強烈且統計上極度顯著的下降趨勢。

Revenue (營收因子)
slope: 0.000018 (正值)
p_value: 0.0048 (顯著)
r_squared: 0.056 (解釋力較弱)
trend: flat (因 r_squared < 0.1)

解讀: 營收因子有統計上顯著的上升趨勢,但由於解釋力不足 (r_squared < 0.1),被歸類為 flat。

Momentum (動能因子)
slope: 0.000093 (顯著正值)
p_value: 1.14e-17 (極度顯著)
r_squared: 0.41 (中等偏強解釋力)
trend: up

解讀: 動能因子的集中度呈現非常強烈且統計上極度顯著的上升趨勢。這是一個明確的信號,表明動能因子非常「熱門」,大量資金正在追逐這個策略。