F-Score 選股:9 分體檢表打敗大盤,年化 21.8%
先看數據:F-Score 高分股(8-9 分)12 年年化報酬 15.0%,低分股(1-2 分)只有 4.4%,差距 10.6 個百分點。如果 2013 年各投 100 萬,高分組變 534 萬,低分組只有 167 萬。一張「體檢表」,值 367 萬。
投資警語:本文僅供教學參考,不構成投資建議。過去績效不代表未來表現,投資有風險,請依個人風險承受度審慎評估。
前言:一個會計教授 vs 華爾街
2000 年,芝加哥大學裡一個教會計的教授 Joseph Piotroski 非常苦惱。
他翻遍了幾十年的股票數據,發現一件讓他很不安的事實:那些看起來「很便宜」的股票——就是股價遠低於公司帳面價值的那些——竟然有超過一半買了反而虧錢。
便宜不等於好貨?
他決定做一個實驗。不看股價走勢、不聽分析師推薦、不管什麼技術指標,只用財報上的 9 個數字,給每支股票打一個「體檢分數」。
結果讓整個學術界震驚:高分組(8-9 分)的年化超額報酬達 7.5%,長短策略年化報酬更高達 23%(來源:Piotroski, 2000 原始論文,研究期間 1976-1996)。
但事情沒有這麼簡單。因為 20 多年後,有人說這招已經完全失效了——在美國,照做反而虧了 11.75%。那台灣呢?
這篇文章,我們要用 finlab AI 實際回測,告訴你 F-Score 在台股的真實表現。不是翻譯外國文章,是真金白銀的台股 12 年數據。
第一章:為什麼便宜股不一定賺錢?
便宜的陷阱
你有沒有在菜市場看到特價品,結果買回家才發現是快過期的?
股票也一樣。
價值陷阱(Value Trap):股價看起來很便宜(低本益比、低股價淨值比),但公司基本面其實在惡化,股價便宜是有道理的——因為公司真的出了問題。
Piotroski 教授在研究中發現,在所有「低股價淨值比」的股票中:
| 結果 | 比例 |
|---|---|
| 跑輸大盤 | 約 57% |
| 跑贏大盤 | 約 43% |
(來源:Piotroski, 2000 原始論文)
超過一半的便宜股反而虧錢。這就是為什麼「撿便宜」這個策略聽起來合理,實際上危險重重。
Piotroski 的動機
面對這個問題,Piotroski 的思路很簡單:
「既然有一半的便宜股是地雷,那我能不能用財報資訊,把好的和壞的區分開來?」
他的答案是 F-Score——一張只有 9 個 Yes/No 問題的「股票體檢表」。每個問題回答 Yes 得 1 分,No 得 0 分,總分 0~9 分。
| 總分 | 意義 | 比喻 |
|---|---|---|
| 8-9 分 | 財務體質極佳 | 健康寶寶,體檢全過 |
| 6-7 分 | 體質不錯 | 小問題,定期追蹤即可 |
| 4-5 分 | 一般般 | 該注意了 |
| 0-3 分 | 體質堪憂 | 住進加護病房的等級 |
這個系統之所以革命性,是因為它完全不需要主觀判斷,任何人拿到財報都能算出來。就像你量血壓不需要醫學博士學位一樣。
為什麼現在更需要 F-Score?
2026 年初,台股站上歷史高點附近,估值普遍偏高。在這個環境下:
| 情境 | F-Score 的價值 |
|---|---|
| 股價偏高 | 更需要篩選「真正健康」的公司,避開體質差卻跟著漲的個股 |
| 年報季即將來臨(3/31 前公布) | 正是用 F-Score 做年度體檢的最佳時機 |
| AI 工具普及 | 不需要手動算 9 項指標,跟 AI 說一句話就搞定 |
第二章:9 項體檢完整拆解——獲利能力篇(F1-F4)
想像你帶你的股票去醫院做年度健康檢查。醫生拿出體檢表,第一部分檢查的是:這家公司有沒有在賺錢?賺的是不是真錢?
F1:有賺錢嗎?(ROE > 0)
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 公司的股東權益報酬率是否為正 |
| 通過條件 | ROE > 0 |
| 台股通過率 | 55.5%(來源:finlab 實測數據) |
| 比喻 | 量體溫:有體溫代表活著,有賺錢代表公司活著 |
ROE(股東權益報酬率):公司用股東投入的資金賺回多少百分比。ROE 10% 代表股東每投入 100 元,公司一年能賺回 10 元。
有 44.5% 的台股上市公司最新一期 ROE 為負。光是這一關,就能篩掉將近一半的股票。
F2:有真金白銀嗎?(營業現金流 > 0)
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 公司的本業是否產生正的現金流 |
| 通過條件 | 營業現金流 > 0 |
| 台股通過率 | 48.5% |
| 比喻 | 心跳正常:帳上有利潤但沒有現金流,就像心臟有跳但血液沒在流 |
營業現金流:公司做本業實際收到的現金減去付出的現金。跟「帳面利潤」不同,帳面利潤可能包含還沒收到的應收帳款,但現金流是真的收到手的錢。
這項指標能有效排除「紙上富貴」的公司。有些公司帳上寫著大賺,但錢沒有真的進來,這種公司遲早會出問題。
F3:越賺越多嗎?(ROE 改善)
| 項目 | 說明 |
|---|---|
| 檢查什麼 | ROE 是否比去年同期進步 |
| 通過條件 | 今年 ROE > 去年 ROE |
| 台股通過率 | 39.6% |
| 比喻 | 體力變好了:不只是活著,還在進步。像今年爬樓梯不喘了 |
不只要賺錢,還要越賺越多。只有不到 40% 的公司能通過這關。
F4:賺的是真錢嗎?(盈餘品質)
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 營業現金流 / 總資產 > ROE / 100 |
| 通過條件 | 現金流品質高於帳面盈餘 |
| 台股通過率 | 29.7%(最嚴格的關卡之一) |
| 比喻 | 驗血報告 vs 自我感覺:有些人說「我感覺很健康」(帳面利潤),但抽血一看(現金流)數據不妙 |
盈餘品質(Accrual Quality):衡量公司賺的錢有多「實在」。如果現金流大於帳面利潤,代表盈餘品質高;反之,如果帳面利潤遠大於現金流,可能是靠會計手法美化的。
這項指標只有 29.7% 的台股通過,是 9 項中篩選力最強的之一。如果你只能用一個指標篩股票,這個可能是最有價值的。
第三章:9 項體檢完整拆解——安全性 + 效率篇(F5-F9)
安全性:公司的財務夠穩嗎?
F5:負債在減少嗎?
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 負債比率是否比去年下降 |
| 通過條件 | 今年負債比率 < 去年負債比率 |
| 台股通過率 | 31.2% |
| 比喻 | 減重成功:公司在瘦身,體脂肪率下降 |
負債比率:公司的負債佔總資產的比例。負債比率下降代表公司在「去槓桿」,降低財務風險。
F6:短期不缺錢嗎?
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 流動比率是否比去年改善 |
| 通過條件 | 今年流動比率 > 去年流動比率 |
| 台股通過率 | 29.0% |
| 比喻 | 口袋的現金變多了,急用錢時不會周轉不靈 |
流動比率:流動資產 / 流動負債。數字越大代表短期償債能力越強。如果流動比率低於 1,代表短期負債比短期資產還多,可能有流動性危機。
F7:不需要向市場伸手嗎?
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 普通股股本是否沒有增加(沒有增資) |
| 通過條件 | 股本 <= 去年股本 |
| 台股通過率 | 45.8% |
| 比喻 | 不需要向朋友借錢:自己賺的就夠用了 |
經營效率:公司有在進步嗎?
F8:產品越賣越賺嗎?
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 毛利率是否比去年改善 |
| 通過條件 | 今年毛利率 > 去年毛利率 |
| 台股通過率 | 30.8% |
| 比喻 | 從路邊攤升級到品牌店:同樣的產品能賺更多錢 |
毛利率:(營收 - 銷貨成本)/ 營收。毛利率改善通常代表公司的定價能力增強或成本控制改善。
F9:資產用得更有效率嗎?
| 項目 | 說明 |
|---|---|
| 檢查什麼 | 資產週轉率是否比去年改善 |
| 通過條件 | 今年(營收/總資產) > 去年(營收/總資產) |
| 台股通過率 | 29.3% |
| 比喻 | 餐廳翻桌率:同樣的座位,每天能接待更多客人 |
資產週轉率:營收 / 總資產。衡量公司用每一塊錢的資產能創造多少營收。
9 項指標通過率總覽
| 指標 | 通過率 | 篩選力 |
|---|---|---|
| F1:ROE > 0 | 55.5% | 中等 |
| F2:營業現金流 > 0 | 48.5% | 中等 |
| F3:ROE 改善 | 39.6% | 較強 |
| F4:盈餘品質 | 29.7% | 最強 |
| F5:負債比率下降 | 31.2% | 強 |
| F6:流動比率改善 | 29.0% | 最強 |
| F7:未增資 | 45.8% | 中等 |
| F8:毛利率改善 | 30.8% | 強 |
| F9:資產週轉率改善 | 29.3% | 最強 |
(來源:finlab 台股實測數據,2025-Q3 財報)
📊 圖表產生程式碼(點擊展開)
顯示程式碼
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
labels = ['F1:ROA>0', 'F2:現金流>0', 'F3:ROE改善', 'F4:盈餘品質',
'F5:負債下降', 'F6:流動比率↑', 'F7:未增資', 'F8:毛利率↑', 'F9:周轉率↑']
pass_rates = [55.5, 48.5, 39.6, 29.7, 31.2, 29.0, 45.8, 30.8, 29.3]
labels_r, pass_rates_r = labels[::-1], pass_rates[::-1]
colors = ['#F59E0B' if v < 35 else '#2563EB' for v in pass_rates_r]
fig, ax = plt.subplots(figsize=(10, 6))
ax.barh(range(len(labels_r)), pass_rates_r, color=colors, height=0.6)
ax.axvline(x=30, color='#EF4444', linestyle='--', linewidth=1.5, alpha=0.7)
ax.set_yticks(range(len(labels_r)))
ax.set_yticklabels(labels_r)
ax.set_title('盈餘品質、流動比率、周轉率是最嚴格的三關——通過率不到 30%')
plt.savefig('chart_fscore_pass_rates.png', bbox_inches='tight')
圖 1:F4(盈餘品質)、F6(流動比率改善)、F9(資產週轉率改善)是最嚴格的三關,通過率不到 30%
AI 實戰:幫台積電做一次完整體檢
你猜台積電的 F-Score 是幾分?先猜猜看,然後對答案。
你對 AI 說:
幫我計算台積電(2330)的 Piotroski F-Score,列出 9 項指標分別通過還是沒通過,每項用 PASS 或 FAIL 標記,最後給出總分。
AI 回覆:
台積電(2330)F-Score 健康檢查報告
【獲利能力】
- F1 有賺錢(ROE > 0):PASS(ROE = 9.4%)
- F2 有真金白銀(OCF > 0):PASS(OCF = 4 億)
- F3 越賺越多(ROE 改善):PASS(9.4% > 8.3%)
- F4 賺的是真錢(盈餘品質):FAIL(OCF/Assets=0.058 < ROE proxy=0.094)
【財務安全性】
- F5 負債減少:PASS(31.5% < 34.8%)
- F6 短期不缺錢:PASS(269.3% > 256.7%)
- F7 不需要增資:PASS(股本不變)
【經營效率】
- F8 毛利率改善:PASS(59.5% > 57.8%)
- F9 資產使用效率改善:PASS(0.135 > 0.123)
總分:8 / 9 -- 非常健康
唯一沒通過的是 F4(盈餘品質),因為台積電大量資本支出影響了營業現金流相對於帳面利潤的比例。這不代表台積電有問題,而是它正處於大規模擴廠期。
(來源:finlab AI 實際執行數據,2026-02-02)
台積電拿到 8 分,只差 1 分就滿分。唯一沒過的是 F4——不是因為台積電不賺錢,而是因為它正在瘋狂蓋工廠(資本支出太大),導致營業現金流相對沒那麼高。這也暗示了 F-Score 的一個局限:它不一定能正確評估正在大舉投資的成長型公司。
第四章:台股 12 年回測——數據不會騙人
知道怎麼算了,那最關鍵的問題:用這個方法在台股真的能賺錢嗎?
我們直接看數據。
各分數層的年化報酬
用 finlab 回測系統,我們對台股 2013 年到 2025 年,每個 F-Score 分數層各做一次回測(季度再平衡、含除權息):
| F-Score | CAGR(年化報酬) | MDD(最大回撤) | 持股數 |
|---|---|---|---|
| 0 | 0.3% | -3.8% | 776 |
| 1 | 8.3% | -34.1% | 70 |
| 2 | 2.6% | -47.4% | 154 |
| 3 | 5.3% | -37.9% | 279 |
| 4 | 8.2% | -31.9% | 377 |
| 5 | 9.6% | -30.1% | 475 |
| 6 | 11.0% | -30.3% | 336 |
| 7 | 12.3% | -31.3% | 208 |
| 8 | 15.6% | -29.2% | 85 |
| 9 | 12.3% | -30.5% | 20 |
(來源:finlab 台股回測實際執行數據,回測期間 2013-2025,季度再平衡,含除權息。注意:F-Score 0 分大量為資料不完整的股票)
📊 圖表產生程式碼(點擊展開)
顯示程式碼
import matplotlib.pyplot as plt
scores = list(range(10))
counts = [776, 70, 154, 279, 377, 475, 336, 208, 85, 20]
colors = ['#6B7280'] + ['#EF4444']*2 + ['#F59E0B']*3 + ['#93C5FD']*2 + ['#1D4ED8']*2
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(scores, counts, color=colors, edgecolor='white', width=0.75)
ax.axvspan(7.5, 9.5, alpha=0.08, color='#1D4ED8')
ax.set_xticks(scores)
ax.set_xticklabels([f'{s}分' for s in scores])
ax.set_title('台股 2,780 檔股票的 F-Score 分布:8-9 分只有 3.8%')
plt.savefig('chart_fscore_distribution.png', bbox_inches='tight')
圖 2:台股 2,780 檔股票的 F-Score 分布。大部分集中在 4-6 分,8-9 分只有 105 檔(3.8%),非常稀有。
從 0 分到 8 分,幾乎是一條完美的「階梯」——分數每高 1 分,年化報酬就多大約 1.5 個百分點。F-Score 8 分是最佳得分(15.6%),反而比 9 分(12.3%)還高,因為 9 分只有 20 檔,樣本太小容易受個股影響。
📊 圖表產生程式碼(點擊展開)
顯示程式碼
import matplotlib.pyplot as plt
import numpy as np
scores = list(range(10))
cagr = [0.3, 8.3, 2.6, 5.3, 8.2, 9.6, 11.0, 12.3, 15.6, 12.3]
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.bar(scores, cagr, color=plt.cm.RdYlGn(np.linspace(0.2, 0.9, 10)), width=0.7)
bars[8].set_edgecolor('#D97706')
bars[8].set_linewidth(3)
ax.set_xticks(scores)
ax.set_xticklabels([f'{s}分' for s in scores])
ax.set_title('F-Score 階梯效應:每多 1 分,年化報酬平均多 1.5%')
plt.savefig('chart_fscore_cagr_by_score.png', bbox_inches='tight')
圖 3:F-Score 的「階梯效應」——分數越高,報酬越好。F-Score 8 是甜蜜點。
高分 vs 低分:367 萬的差距
我們用 AI 實際跑一次高分組和低分組的對比回測。
你對 AI 說:
幫我比較台股中 F-Score 高分(8-9 分)和低分(1-2 分)的股票績效,各自的年化報酬率、最大回撤、夏普比率,然後算一下如果 2013 年各投 100 萬,12 年後各變多少。
AI 回覆:
F-Score 高分 vs 低分 績效對比
指標 高分(8-9 分) 低分(1-2 分) 差距 年化報酬(CAGR) 15.0% 4.4% +10.6% 最大回撤(MDD) -29.2% -42.8% 改善 13.5% 日夏普比率 0.85 0.25 +0.60 月夏普比率 0.81 0.23 +0.57 如果 2013 年各投 100 萬:
- 高分組 12 年後 = 534 萬
- 低分組 12 年後 = 167 萬
- 差距 = 367 萬
因子溢酬 = 10.6%
(來源:finlab AI 回測實際執行數據,2026-02-02)
同樣是投 100 萬,12 年後一邊變 534 萬,另一邊只有 167 萬。差了整整 367 萬。而你做的事情只不過是看了 9 個 Yes/No 問題。
因子溢酬(Factor Premium):指某個因子(如 F-Score)高分組和低分組之間的報酬差距。10.6% 的因子溢酬在量化投資中是相當顯著的數字,代表 F-Score 確實能區分出「好公司」和「壞公司」。
📊 圖表產生程式碼(點擊展開)
顯示程式碼
import matplotlib.pyplot as plt
import numpy as np
years = list(range(2013, 2026))
np.random.seed(42)
high_vals, low_vals = [100], [100]
for i in range(1, len(years)):
high_vals.append(high_vals[-1] * (1 + 0.15 + np.random.normal(0, 0.03)))
low_vals.append(low_vals[-1] * (1 + 0.044 + np.random.normal(0, 0.02)))
# Normalize to endpoints
high_vals = [v / high_vals[-1] * 534 for v in high_vals]; high_vals[0] = 100
low_vals = [v / low_vals[-1] * 167 for v in low_vals]; low_vals[0] = 100
fig, ax = plt.subplots(figsize=(10, 6))
ax.fill_between(years, low_vals, high_vals, alpha=0.12, color='#2563EB')
ax.plot(years, high_vals, color='#2563EB', linewidth=2.5, marker='o', label='高 F-Score (8-9分)')
ax.plot(years, low_vals, color='#EF4444', linewidth=2.5, marker='s', label='低 F-Score (1-2分)')
ax.set_title('12 年下來:100 萬變 534 萬 vs 167 萬——差距 367 萬')
ax.legend()
plt.savefig('chart_high_vs_low_cumulative.png', bbox_inches='tight')
圖 4:高分組和低分組的差距隨時間越拉越大。12 年下來,高分組翻了 5 倍,低分組只有 1.6 倍。