
你一定懂那種瞬間——螢幕上跳出一檔飆股,心裡直覺「它會漲」。但直覺不會每次都對。於是我們決定反過來做:把靈感拆成可驗證的「因子」,把「為什麼漲」說清楚,然後用資料驗證。
難嗎?不簡單。因為我們有工具可以把難的事做得乾淨俐落。
和一般做法,哪裡不一樣?
一般做法:先選幾個看起來厲害的指標,湊一套回測;結果好就覺得是神功,結果差就再換一套。
我們的做法:先把策略拆解,再逐一檢驗每個因子的線索:它帶來的超額報酬是多少?在什麼狀態下有效?會不會太擁擠(大家都在用)?彼此相關性高不高?
沒有 Finlab 我們得自己處理:資料下載、清洗、對齊、換股對齊、月/季頻率對接… 一個環節錯了,結果就不可信。
有了 finlab,我們可以直接用一致頻率的資料集與安全的 resample 邏輯,把時間對齊、避免偷看未來;剩下的,就是認真跟資料搏鬥。
我們的範例策略:
三個最基本、卻常被忽略「為什麼」的因子:市值、營收動能、價格動能。
- 為什麼要小市值?因為小市值在資訊修正與資金挹注時,彈性常常更大。
- 為什麼看營收加速?因為是最扎實的推力。
- 為什麼要動能?因為市場的從眾與慣性,往往延長趨勢。
from finlab import data, backtest
marketcap = data.get('etl:market_value')
revenue = data.get('monthly_revenue:當月營收')
close = data.get('price:收盤價')
cond_smallcap = marketcap.rank(pct=True, axis=1) < 0.3
cond_revgro = (revenue.average(3) / revenue.average(12)).rank(pct=True, axis=1) > 0.7
cond_momentum = (close / close.shift(20)).rank(pct=True, axis=1) > 0.7
pos = cond_smallcap & cond_revgro & cond_momentum
report = backtest.sim(pos, resample='ME', upload=False)
report.display()
為什麼要用 rank?比較的是「相對位置」,而不是絕對數值。

把策略拆成可驗證的語言:特徵 & 標籤
先定義我們「到底要預測什麼」:未來一段時間的超額報酬(相對市場平均)。這是策略的真目標,而不是單看漲跌。
from finlab import data
import finlab.ml.feature as feature
import finlab.ml.label as label
features = feature.combine({
'marketcap' : cond_smallcap,
'revenue' : cond_revgro,
'momentum' : cond_momentum
}, resample='ME')
labels = label.excess_over_mean(index=features.index, resample='ME')
為什麼用超額報酬? 因為我們將焦點從「追隨市場」轉向「超越對手」。我們比較的不是大盤的絕對速度,而是相對於競爭者的反應速度。
因子報酬(Factor Return):它到底有沒有賺到「解釋力」?
把每個因子的「獨立效果」抽出來,看長期累積報酬線條。線條不只代表報酬,更是「這個因子值得被相信」的證詞。
from finlab.tools.factor_analysis import calc_factor_return
from finlab.plot import plot_line
factor_return = calc_factor_return(features, labels).cumsum()
plot_line(factor_return, unit='.0%', title='因子累積報酬')

為什麼先看累積線? 因為短期雜訊會騙人,長期線條的斜率與轉折,才能看出它是偶然還是規律。
因子集中度(Centrality):因子擁擠嗎?
當一個因子被同時大量採用,接著因子趨向擁擠、碰到回檔風險上升。我們用主成分分析的權重,量化「共同性」。
- 數值大:近期用它選股都賺,表示擁擠;下一步要警戒回檔。
- 數值小:近期表現差,反而可能接近「冷門反擊」的起點。
from finlab.tools.factor_analysis import calc_centrality
centrality = calc_centrality(calc_factor_return(features, labels), 12)
plot_line(centrality, title='因子集中度')

為什麼要看擁擠度? 因為市場是動態的,當所有人一起衝進同一個因子,邊際報酬就會變脆弱。
因子貢獻度 (Shapley Values):把功勞分清楚
我們不只看「有賺」,還要知道「誰在出力」。Shapley 用公平分配的方式,拆解各因子的邊際貢獻。
from finlab.tools.factor_analysis import calc_shapley_values
shapley = calc_shapley_values(features, labels)
plot_line(centrality, title='因子貢獻度')

為什麼要拆貢獻? 因為多因子策略容易「誰都沾一點」,但在壓力時刻,你要知道要砍誰、留誰。
IC(Information Coefficient):預測力的體檢表
我們把分數和未來報酬做相關(可用 rank),長期 IC 穩定偏正、且不是只靠少數極端時期拉高,才叫做真正的「可預測」。
from finlab.tools.factor_analysis import calc_ic
features_ic = {
'marketcap': -marketcap, # 小市值用負號
'revenue' : revenue.average(3) / revenue.average(12),
'momentum' : close / close.shift(20),
}
features_ic = feature.combine(features_ic, resample='ME')
ic_df = calc_ic(features_ic, labels, rank=True)
plot_line(ic_df, title='因子相關性')

為什麼要看 IC? 因為報酬可能來自風格或偶然,但「相關性」在長期裡更難偽裝。
趨勢偵測:隨時間變化數值
我們用回歸去看「集中度、貢獻、IC」的趨勢:上升?下降?還是平?
from finlab.tools.factor_analysis import calc_regression_stats
centrality_trend = calc_regression_stats(centrality)
- p 值小 + 斜率正:真正在升溫;
- p 值小 + 斜率負:退潮真正發生;
- 解釋力低(R²小):暫時別下定論,當它不存在。
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
解讀: 動能因子的集中度呈現非常強烈且統計上極度顯著的上升趨勢。這是一個明確的信號,表明動能因子非常「熱門」,大量資金正在追逐這個策略。
為什麼做趨勢? 因為資金有輪動。與其死守某一信仰,不如跟著證據調整權重。
總結
解決分析前的難點
- 多頻資料對齊:日價、月營收、季財報……沒有統一索引會災難。
- 風險:偷看未來、不同頻率窗口誤用,都會讓結果「看起來很美」。
- 擁擠:策略跑出來以後,大家都用,它就不香了。這就是為什麼Centrality與趨勢偵測是必要的。
- 因子工具把「報酬、擁擠、貢獻、IC」變成可重複的研究流程。
行動建議:你可以直接用這篇當「研究框架」模板
- 用 feature.combine/label.excess_over_mean 定義問題;
- 跑 因子報酬 / 集中度 / Shapley / IC / 趨勢 五件套;
- 用趨勢結果去調整權重,而不是迷信單因子。
歡迎參考 Colab 範例檔