跳至主要內容
台股研究 約 9 分鐘閱讀

data.indicator() 一行算全台股技術指標(TA-Lib Python 回測)

用 finlab 的 data.indicator() 一行就把 KD、RSI、MACD、ATR 等 TA-Lib 上百種技術指標算到全台股 2700 多檔、近 19 年的資料上,回傳可直接丟進回測的 FinlabDataFrame。文中附 RSI 超賣均值回歸的真實台股回測(2016 到 2026,對比含息 0050)與可下載 strategy.py,示範指標到底該怎麼用在 Python 量化選股。

data.indicator 一行算出的 KD 指標疊在台積電 2330 股價上,含 K 值與 D 值雙線與超買超賣區

先講最有用的一件事:在 finlab 裡,算一個技術指標到全台股,只要一行。

顯示程式碼
from finlab import data
 
rsi = data.indicator("RSI", timeperiod=14)

這一行回傳的 rsi,欄是全部上市櫃股票代號、列是日期,涵蓋約 2700 多檔股票、近 19 年的歷史。它是一個 FinlabDataFrame,可以直接放進選股條件與 sim() 回測,不需要再為每一檔股票寫迴圈。實際跑出來,這個指標矩陣的形狀大約是 4700 個交易日 × 2759 檔股票,資料從 2007 年 4 月一路接到 2026 年 6 月。

這篇文章用 RSI、KD、MACD、ATR 四個最常被問到的指標當例子,先示範 data.indicator() 的算法與特色,再附一個用 RSI 當訊號源的真實台股回測(結果輸給含息 0050,但這正是重點),最後給可下載的 strategy.pydata.csv 讓你自己重現。

關鍵數字:一行 data.indicator() 算出什麼

下面這張表是 2026-06-26 當天,data.indicator() 在台積電 2330 上算出的真實指標值,全部來自下方可下載的腳本,沒有一個是手填的:

指標 data.indicator() 呼叫 2330 當日真實值 白話一句話
RSI(14) data.indicator("RSI", timeperiod=14) 50.16 量近期漲跌力道,>70 偏超買、<30 偏超賣,當天 2330 在中性偏多
KD 的 K 值 k, d = data.indicator("STOCH") 10.70 收盤落在近期高低區間的相對位置,K<20 為低檔區
KD 的 D 值 同上(第二個回傳值) 36.67 K 的平滑線,K 向上穿過 D 是黃金交叉
MACD macd, signal, hist = data.indicator("MACD") 41.57 快慢均線差,衡量中期動能方向
MACD 柱(hist) 同上(第三個回傳值) -5.58 MACD 減訊號線,當天為負代表短線動能轉弱
20 日均線(還原價) data.indicator("SMA", adjust_price=True, timeperiod=20) 5223.06 還原權息後的 20 日平均成本

把同一個 RSI 套到當天有正常交易、且 60 日均量大於 500 萬股的流動股票池(約 402 檔)上,可以一眼看到全市場的多空溫度:RSI 中位數 49.8,落在 30 以下的超賣股只有 7 檔,70 以上的超買股有 15 檔。這代表那一天台股整體不算過熱、也沒有恐慌,是個相對平衡的位置。下面這張全市場 RSI 分布圖,就是這一行算出來的成果:

一行 data.indicator 算出流動性股票池 402 檔的 RSI 分布直方圖,標出 30 超賣線、70 超買線與全市場中位數 49.8

這就是 data.indicator() 相對於傳統寫法最大的差別。早年要算技術指標,得先把每一檔股票的開高低收量整理成字典,再對每一檔跑一次 TA-Lib,最後把結果塞回 DataFrame。同樣的事,data.indicator() 一行就替全市場做完,而且回傳的是可以直接回測的格式。

data.indicator() 的幾個特色

data.indicator() 底層是呼叫 TA-Lib 的 abstract 模組,把指標套到 finlab 的全市場價格資料上。它有幾個讓回測變簡單的設計:

  • 一行算全市場:傳指標名稱(例如 "RSI""STOCH""MACD""ATR"),回傳整個市場的指標矩陣,不必逐檔迴圈。
  • 多輸出自動拆開:像 KD(STOCH)會回傳 K、D 兩個矩陣,MACD 會回傳 MACD 線、訊號線、柱狀圖三個矩陣,用多重指定接住即可。
  • adjust_price 用還原股價:傳 adjust_price=True 會改用還原權息後的價格來算指標,避免除權息當天的價格跳空污染均線與通道類指標。
  • resample 換頻率:傳 resample="W"resample="M" 可以直接算週線、月線的指標,不用自己先降頻。
  • market 切換台股 / 美股:搭配 data.set_market("us") 後再呼叫,同一行就能算美股的指標。
  • **kwargs 改參數:TA-Lib 的參數直接當關鍵字傳進去,例如 data.indicator("RSI", timeperiod=10)data.indicator("STOCH", fastk_period=9),把教科書常用的 KD(9、3、3)一秒設好。
  • 回傳 FinlabDataFrame:結果可以直接和其他條件做布林運算(例如 rsi < 30),再丟進 sim() 回測,中間不用轉格式。

至於指標總數,TA-Lib 本身提供約 158 個函式(用 talib.get_functions() 可列出完整清單),涵蓋重疊研究、動量、成交量、波動度、型態辨識等大類;若再加上 pandas-ta,可用的指標達到上百種。data.indicator() 支援的就是這個 TA-Lib(或 pandas-ta)函式庫,名稱與參數和 TA-Lib 文件一致,所以查到的任何一個指標都能套用到全台股。

到這裡你已經知道它能做什麼了。如果想直接照這篇把環境裝好、把指標算出來,用下面這句提示詞讓 AI 幫你設定 FinLab、抓好台股資料、跑通 data.indicator()

免費試用

用 AI 開始 FinLab

把這句話交給你的AI,它會帶你完成設定並做出第一個策略。

告訴你的AI:

幫我設定 FinLab,用 data.indicator 計算台股技術指標並回測,請讀:https://finlab.finance/setup?relatedUrl=/blog/python-talib-158-technical-indicators

關於安裝:data.indicator() 需要環境裡有 TA-Lib 或 pandas-ta。過去 TA-Lib 因為要先裝 C 語言函式庫而難搞,現在大多數平台已經可以直接 pip install ta-lib 裝好(背後改用預編譯套件)。finlab 套件本身的取得,照上面 AI 輔助設定流程準備就會把這些依賴一併處理好,你不需要手動拼湊環境。

四個指標的 data.indicator() 寫法

下面四段是這篇示範的四個指標。每一段都附一句白話的「它在量什麼、典型怎麼讀」,讓你不只看得懂程式碼,也知道訊號代表什麼。

KD(STOCH):收盤在區間裡的相對位置

KD 量的是「今天收盤落在最近一段高低區間的哪個位置」,數值在 0 到 100 之間。典型讀法是 K 向上穿過 D 形成黃金交叉、且位置在低檔(K<20)時,視為短線轉強的訊號;反過來在高檔(K>80)死亡交叉則是轉弱。

顯示程式碼
from finlab import data
 
# STOCH 是多輸出指標,一行同時拿到 K 與 D 兩個全市場矩陣
k, d = data.indicator("STOCH")
 
# 看台積電 2330 最近一筆
print(k["2330"].dropna().iloc[-1])   # 2026-06-26:10.70
print(d["2330"].dropna().iloc[-1])   # 2026-06-26:36.67

文章開頭那張縮圖,就是把這兩條線疊在台積電 2330 的還原股價上畫出來的。當天 2330 的 K 值只有 10.70、落在低檔區,而 D 值還在 36.67,K 尚未向上穿過 D,屬於低檔但還沒出現黃金交叉的狀態。

RSI:近期漲跌力道的擺盪指標

RSI(Relative Strength Index,相對強弱指標)由 Wilder (1978) 在《New Concepts in Technical Trading Systems》提出,把一段期間內的上漲幅度與下跌幅度相比,換算成 0 到 100 的數值。典型讀法是 RSI 低於 30 視為超賣、高於 70 視為超買。

顯示程式碼
from finlab import data
 
rsi = data.indicator("RSI", timeperiod=14)
 
# 全市場一次到位:今天有多少檔超賣、多少檔超買
liquid = data.get("price:成交股數").rolling(60).mean() > 5_000_000
today = rsi.iloc[-1][liquid.iloc[-1]].dropna()
print((today < 30).sum())   # 全市場超賣檔數:7
print((today > 70).sum())   # 全市場超買檔數:15

把 RSI 算到全市場之後,它不只能看單一檔,還能聚合成「市場廣度」:當天超賣 7 檔、超買 15 檔,就是一個橫截面的多空溫度計。等一下的回測就是用這個 RSI<30 的超賣訊號當進場條件。

MACD:中期動能的方向

MACD 是兩條不同週期指數均線的差,再對它取一條訊號線,兩者相減就是柱狀圖(histogram)。典型讀法是 MACD 線向上穿過訊號線(柱狀圖由負轉正)視為動能轉強。要注意的是,柱狀圖在台股實測比較像是反轉的提示而非順勢的動能訊號,這點在 MACD 台股 11 年回測 有完整的拆解。

顯示程式碼
from finlab import data
 
# MACD 是三輸出指標:macd 線、訊號線、柱狀圖
macd, macd_signal, macd_hist = data.indicator("MACD")
 
print(macd["2330"].dropna().iloc[-1])        # 41.57
print(macd_signal["2330"].dropna().iloc[-1]) # 47.15
print(macd_hist["2330"].dropna().iloc[-1])   # -5.58(為負,短線動能偏弱)

2026-06-26 當天,台積電 2330 的 MACD 線(41.57)還在訊號線(47.15)下方,柱狀圖為 -5.58,代表那段時間短線動能偏弱、尚未轉強。

ATR:波動度的絕對大小

ATR(Average True Range,平均真實區間)量的是一檔股票每天的平均波動幅度,是個以「元」為單位的絕對波動度,常被用來設停損距離或做部位大小控制(波動越大、單位風險越高,部位就配越小)。它本身沒有超買超賣的概念,是個風控用的尺。

顯示程式碼
from finlab import data
 
# 一行算全市場 ATR;adjust_price=True 用還原股價避免除權息跳空
atr = data.indicator("ATR", adjust_price=True, timeperiod=14)
 
# atr 是 FinlabDataFrame,可用來算「波動度過濾」或停損距離
print(atr.shape)   # 例如 (4700+, 2700+):全市場、全歷史一次到位

ATR 的完整台股回測、以及怎麼用它搭出肯特納通道(Keltner Channel)做停損停利,整理在 ATR 指標與肯特納通道台股回測。這裡只示範它一樣是一行 data.indicator() 就算到全市場。

一個真實回測:RSI 超賣均值回歸(輸給 0050)

光會算指標沒有意義,關鍵是把它放進回測看它到底有沒有用。這裡用最直覺的一種用法當例子:每個月在流動股票池裡,買進所有 RSI(14) 低於 30 的超賣股,等權持有,月底再平衡。直覺上這是「跌深反彈、均值回歸」的賭注。

結果如何?把它和同一段期間、同一視窗的含息 0050 擺在一起,差距非常清楚:

指標 RSI 超賣均值回歸 0050 含息
年化報酬(CAGR) -2.03% 23.99%
總報酬 -18.9% 851.1%
日夏普 0.06 1.24
月夏普 0.04 1.16
日索提諾 0.07 1.67
最大回撤 -67.77% -33.96%
平均持股數 7.6 檔 1 檔

RSI 超賣均值回歸策略與 0050 含息累積淨值對照圖,log 軸,策略長期落後 0050

在本文設定下、2016 到 2026 這段期間,這個單純的 RSI 超賣策略年化是 -2.03%,總報酬甚至為負(-18.9%),而同期含息 0050 年化 23.99%、總報酬 851.1%。不只報酬輸,風險還更大:策略最大回撤 -67.77%,比 0050 的 -33.96% 深了一倍。日夏普 0.06 對上 0050 的 1.24,連同一個量級都談不上。

策略與 0050 含息的回撤對照圖,策略回撤最深達 -67.77%,明顯深於 0050 的 -33.96%

為什麼會這麼差?因為台股具有強烈的動能特性,這在 Jegadeesh & Titman (1993) 的動能效應,以及 Asness, Moskowitz & Pedersen (2013) 跨市場的驗證裡都有記錄:過去中期的贏家傾向繼續贏。RSI 低於 30 的股票,在台股多半是「下跌中繼」而不是跌深反彈的候選,用 RSI 超賣去接它們,等於系統性地買進正在走弱的股票,愈攤愈低。這也和擺盪指標被廣泛使用後容易失效的觀察一致,Lo, Mamaysky & Wang (2000) 在用統計方法檢驗技術型態的研究中就指出,技術訊號的價值高度取決於市場結構與使用方式,而非訊號本身。

這個結果說明的是指標的正確定位:RSI 的價值在於「把全市場一次算出來,當成一個橫截面的訊號層或風控層」,再搭配其他選股核心使用,而非單獨拿一個門檻當買賣聖杯。把 RSI 改當動能因子(買強勢、避開弱勢)的完整實測,在 RSI 台股 11 年回測 有反過來的結論。

下面是這個 RSI 超賣回測的互動式報告,可以自己拉時間軸、看每段的部位與報酬:

回測方法與口徑

為了讓上面的數字可被檢驗,這裡把回測設定講清楚:

  • 回測區間:2016-01-01 到 2026-06-26,全段為樣本內(in-sample),本文未另做樣本外切分,這個結論是「單一 RSI 超賣門檻在這段期間的表現」,不宜外推成所有期間。
  • 股票池與流動性過濾:上市櫃股票,並用 60 日均量大於 500 萬股做流動性過濾,避免回測買得到、實單買不到。
  • 交易成本:用 finlab sim() 的台股預設,手續費 0.1425%(打 5 折)並已內扣賣出證交稅 0.3%。
  • 再平衡與權重:月頻再平衡、符合條件者等權持有,平均同時持有約 7.6 檔。
  • 滑價與容量:本文未額外假設滑價,也未估算策略容量;實際衝擊取決於資金規模與個股成交量。
  • 前視偏差:指標用當期收盤後可得的價量資料計算,月底依當時可得資料換股。
  • 基準:0050 含息,用 etl:adj_close 還原價在同一視窗以 .loc 對齊後做買進持有,未經 sim()、不含交易成本。日夏普與月夏普分別以日頻、月頻年化,兩者口徑不同不可直接互比。

這段把方法攤開,是為了讓你判斷數字的可信度,而不是只看一個漂亮(或難看)的年化數字。

從一行指標到完整策略

data.indicator() 的真正用途,是當作你選股流程的零件。常見的接法是:用一個指標的全市場矩陣做布林條件、和基本面或籌碼面條件做交集,再把結果丟進 sim()。例如把 RSI 當成廣度風控(全市場超賣股太多時降曝險)、把均線當成趨勢濾網、把動能當成主選股因子,三者性質不同,疊起來才有互補。

如果你想看各個指標單獨當因子、或搭成完整策略後在台股的真實成績,可以從這幾篇接著讀:

這篇接續 Python 時間序列實作 的資料整理基礎;想看用深度學習解析 K 線、預測股價的延伸,可以參考 MI-LSTM 股價預測論文台股實測。指標名詞的定義可查 量化交易詞彙表。把指標組成可驗證的完整策略、再做風險評估的全貌,整理在 量化交易完整指南

自己重現這篇的回測

文章裡每一個數字都來自下面這支腳本,可以直接下載重跑:

腳本登入只需要一行 finlab.login(),finlab 會在需要資料時自動引導你完成登入,不需要在程式碼裡填任何金鑰。把它跑起來,就能複製出本文的指標範例值與 RSI 超賣回測。

常見問題

Q:data.indicator() 和自己用 TA-Lib 有什麼差別? TA-Lib 一次只算一檔股票的序列,你得自己對每一檔迴圈、再把結果組回 DataFrame。data.indicator() 直接回傳全市場、全歷史的指標矩陣(FinlabDataFrame),可以馬上拿來做選股條件與 sim() 回測,省掉資料整理與迴圈。

Q:到底有幾種指標可以算? TA-Lib 本身約 158 個函式,用 talib.get_functions() 可列出完整清單;再加上 pandas-ta,可用的指標達上百種。data.indicator() 的指標名稱與參數和 TA-Lib 一致,查到的指標基本都能套用。

Q:TA-Lib 還是很難安裝嗎? 現在大多數平台已經可以直接 pip install ta-lib 裝好,不再需要手動編譯 C 函式庫。若用上面的 AI 輔助設定流程準備環境,這些依賴會一併處理好。

Q:怎麼改 KD 或 RSI 的參數? 直接把 TA-Lib 的參數當關鍵字傳進去。例如 data.indicator("RSI", timeperiod=10)data.indicator("STOCH", fastk_period=9) 就能把 KD 設成教科書常用的 9、3、3。

Q:adjust_price 什麼時候要設 True? 算均線、通道、ATR 這類和「價格水準」有關的指標時建議設 adjust_price=True,用還原權息後的價格,避免除權息當天的跳空把指標扭曲。純粹的擺盪指標(如 RSI、KD 用的是相對位置)影響較小。

Q:單一技術指標可以直接當買賣訊號嗎? 本文的 RSI 超賣回測說明了風險:單一門檻在台股 2016 到 2026 年化 -2.03%、最大回撤 -67.77%,輸給含息 0050 一大截。指標適合當橫截面的訊號層或風控層,搭配其他選股核心使用,而不是單獨當聖杯。

Q:可以算美股的指標嗎? 可以。先 data.set_market("us") 切到美股,再呼叫 data.indicator(),同一行就會算美股的指標矩陣。


最後更新:2026-06|回測區間:2016-01 到 2026-06|作者:FinLab 量化研究團隊(經量化研究員審閱)

本文僅供量化研究與教學用途,所有指標值與回測數字均由 finlab 套件在真實台股資料上產出,過去績效不代表未來表現,不構成投資建議。文中 RSI 超賣均值回歸策略全段最大回撤 -67.77%、年化為負,僅作為「單一指標不宜直接當買賣訊號」的反面教材,實際交易前請自行評估風險、滑價與交易容量。

FinLab AI

想建立自己的策略?

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

免費開始

更多技術指標研究

查看全部