FinLab

因子分析實戰:3 因子選股策略從靈感到回測

August 22, 2025

封面圖片 封面圖片

你一定懂那種瞬間——螢幕上跳出一檔飆股,心裡直覺「它會漲」。但直覺不會每次都對。於是我們決定反過來做:把靈感拆成可驗證的「因子」,把「為什麼漲」說清楚,然後用資料驗證。

難嗎?不簡單。因為我們有工具可以把難的事做得乾淨俐落。

因子分析和一般做法,哪裡不一樣?

一般做法:先選幾個看起來厲害的指標,湊一套回測;結果好就覺得是神功,結果差就再換一套。

我們的做法:先把策略拆解,再逐一檢驗每個因子的線索:它帶來的超額報酬是多少?在什麼狀態下有效?會不會太擁擠(大家都在用)?彼此相關性高不高?

沒有 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')

為什麼用超額報酬? 因為我們將焦點從「追隨市場」轉向「超越對手」。我們比較的不是大盤的絕對速度,而是相對於競爭者的反應速度。

想建立自己的策略?

用自然語言描述你的選股想法,AI 自動驗證、回測、給你答案

免費開始