「台股」對工程師抓資料的 trap:TWSE 和 TPEx 是兩個獨立市場
工程師或 dev-leaning 散戶在寫 script 抓「台股」資料時,有一個常見的 coverage gap:直覺 GET 一個 TWSE(上市)endpoint,以為已覆蓋「台股全市場」,實際上漏掉整個 TPEx(上櫃)市場。台股並非單一交易所,而是由 TWSE 和 TPEx 兩個獨立機構、兩個獨立 API base 組成。兩邊各有各的每日報價 endpoint、各有各的三大法人買賣超 endpoint,資料不互通。
本文整理兩市場的制度差異、API endpoint 對照、以及 TWSE-only 抓資料工具對哪類持倉會造成盲點。
① 台股 = TWSE(上市)+ TPEx(上櫃)兩個獨立市場
台股在制度面由兩個交易所組成,各有獨立的監管架構、掛牌標準和指數體系:
| 面向 | TWSE(台灣證券交易所,上市) | TPEx(證券櫃檯買賣中心,上櫃) |
|---|---|---|
| 全名 | Taiwan Stock Exchange | Taipei Exchange(2015 由 GreTai 改名) |
| 主要指數 | 加權股價指數(TAIEX) | 上櫃指數(OTC Index) |
| 掛牌門檻 | 較高(資本額、獲利年限、股東人數等) | 較低(成長型中小企業友善) |
| 代表性公司類型 | 台積電、聯電、鴻海等大型權值股 | 中小型科技股、生技股較多 |
| API base URL | https://www.twse.com.tw/ | https://www.tpex.org.tw/openapi/v1/ |
| OpenAPI Swagger | https://openapi.twse.com.tw/ | https://www.tpex.org.tw/openapi/ |
掛牌標準和指數分離意味著:當財經新聞報導「台股三大法人昨日買超」,通常指的是 TWSE 上市市場的 T86 資料;上櫃市場的三大法人動向是另一個 endpoint、另一張報表,不在同一個回傳結果裡。
② TWSE endpoint 涵蓋什麼(不涵蓋什麼)
TWSE 的三大法人買賣超資料來自 T86 endpoint:
GET https://www.twse.com.tw/rwd/zh/fund/T86?date={YYYYMMDD}&selectType=ALL&response=json
此 endpoint 回傳當日上市股票的外資、投信、自營商買賣超,每交易日 17:30 後更新。涵蓋範圍:
- TWSE 掛牌的上市股票(含台積電、聯電、大型 ETF 如 0050、00919、0056 等)
- 三大法人分欄:
外陸資買賣超股數(不含外資自營商)/投信買進股數/自營商買進股數
不涵蓋:任何 TPEx 掛牌的上櫃股票。上櫃個股、上櫃 ETF、上櫃生技股的三大法人動向,T86 endpoint 完全沒有。
③ TPEx endpoint 對:每日收盤 + 三大法人
TPEx 有自己的 OpenAPI,兩個核心 endpoint 對應 TWSE 的報價 + T86:
上櫃每日收盤資料
GET https://www.tpex.org.tw/openapi/v1/tpex_mainboard_daily_close_quotes
回傳上櫃股票當日的開高低收、成交量等基本報價資料。欄位命名採英文(不同於 TWSE T86 的中文欄位名稱):
| 欄位 | 說明 |
|---|---|
SecuritiesCompanyCode | 公司代號 |
CompanyName | 公司名稱 |
Close | 收盤價 |
Open | 開盤價 |
High | 最高價 |
Low | 最低價 |
TradingShares | 成交股數 |
TransactionAmount | 成交金額 |
Change | 漲跌 |
NextLimitUp | 次日漲停參考 |
NextLimitDown | 次日跌停參考 |
(部分核心欄位列示 · 完整欄位含 Average / TransactionNumber / LatestBidPrice / LatesAskPrice / Capitals / NextReferencePrice 等共 18 個 · 以官方 OpenAPI Swagger 為準。注意 TPEx upstream 欄位名 LatesAskPrice 為實際 typo · 對接時需 verbatim 對齊,不可糾正為 LatestAskPrice,否則 schema mapping 會 silent miss)
上櫃三大法人買賣超(對應 TWSE T86)
GET https://www.tpex.org.tw/openapi/v1/tpex_buyandsell
提供上櫃市場外資、投信、陸資的買賣超彙總資料,結構邏輯類似 TWSE T86,但是獨立的 endpoint,回傳的是 TPEx 掛牌股票的法人數據。
④ 為何工程師抓資料容易誤判 coverage
抓資料時出現 coverage gap 有三個常見模式:
Gap 1:以為「台股 API」等於全市場
工程師搜尋「台股法人資料 API」,最先找到 TWSE openapi.twse.com.tw,拿到 T86 response,看到有幾百筆 stock 資料,直覺認為「已經涵蓋台股」。實際上 TPEx 上櫃市場的個股近 900 檔(另含 ETF / ETN / 權證等共破萬筆證券),完全不在 T86 的 response 裡,不是空陣列,是根本不存在。
Gap 2:欄位命名差異造成橋接困難
TWSE T86 使用中文欄位名(如 外陸資買賣超股數(不含外資自營商)),TPEx tpex_mainboard_daily_close_quotes 使用英文欄位名(如 SecuritiesCompanyCode)。兩市場的 schema 語言不統一,若工程師習慣 TWSE 欄位後去接 TPEx,需要重新 mapping,不是直接替換。欄位命名的不一致也提高了 silent failure 風險:用 TWSE 的欄位 key 去 parse TPEx response,不會 throw error,只會拿到 undefined,若沒有 schema validation 就靜默略過。
Gap 3:市場代表性混淆
財經新聞報導「外資昨日買超 XX 億」,指的通常是 TWSE 上市市場 T86 的外陸資合計。但聽到這個數字的散戶,若持有上櫃個股,這個「外資動向」並不包含他所持有標的的法人籌碼。兩個市場的法人數字是並排的兩份報告,不是一份。
⑤ 對 Persona A 持倉的盲點
持有 ETF 為主的 Persona A(上班族散戶)日常觀察的多為 TWSE 上市市場指標,0050、00919、0056 這類高股息或市值型 ETF 均掛牌於 TWSE,TWSE-only 工具對這部分持倉的法人資料是完整的。
但以下情況下,TWSE-only 工具存在覆蓋缺口:
- 持有上櫃掛牌個股:部分中小型科技股、生技股掛牌於 TPEx,T86 不含這些股票的三大法人數據
- 持有成分股含上櫃股的 ETF:某些主題型 ETF(如特定生技 ETF)的成分股中包含上櫃個股,若工具只抓 TWSE 法人數據,對 ETF 的成分股分析是不完整的
- 比較市場間資金流動:若要觀察資金是否從上市轉移到上櫃(或反向),需要同時有兩個市場的法人數據才能計算
對資金主要在 TWSE 大型 ETF 的 Persona A 而言,這個盲點在日常操作層面影響有限;但對有部分上櫃持倉的 dev-leaning 散戶,若 workflow 只 GET TWSE 資料,上櫃部分的法人籌碼會是 silent miss 而非 explicit error,排查時不易察覺。
⑥ 正確抓兩邊的 minimum endpoint pair
若 workflow 需要同時覆蓋上市 + 上櫃市場的三大法人資料,minimum endpoint pair 如下:
// 上市三大法人(TWSE T86)
const twseUrl = `https://www.twse.com.tw/rwd/zh/fund/T86?date=${date}&selectType=ALL&response=json`;
// 上櫃三大法人(TPEx tpex_buyandsell)
const tpexUrl = `https://www.tpex.org.tw/openapi/v1/tpex_buyandsell`;
// 上市每日報價(TWSE openapi · 預設回傳最新交易日全市場 array)
const twseQuotesUrl = `https://openapi.twse.com.tw/v1/exchangeReport/STOCK_DAY_ALL`;
// 上櫃每日報價(TPEx · 預設回傳最新交易日)
const tpexQuotesUrl = `https://www.tpex.org.tw/openapi/v1/tpex_mainboard_daily_close_quotes`;
注意事項:
- TWSE T86 的欄位名稱為中文,TPEx tpex_buyandsell 的欄位需對照 TPEx OpenAPI Swagger 確認(兩市場 schema 不通用)
- TWSE T86 需要帶
datequery param;openapi.twse.com.tw 的 STOCK_DAY_ALL 與 TPEx endpoint 預設回傳最新一個交易日資料,不需 date param。若需查詢歷史日期,建議以官方 OpenAPI Swagger 實測確認 date param 行為 - 假日行為:TWSE T86 回傳
{ "stat": "很抱歉,沒有符合條件的資料!" }而非空陣列;TPEx 行為建議以 OpenAPI Swagger 實測確認 - 兩市場的 stock code 由 TWSE / TPEx 統一以 ISIN 框架編碼,代號全市場唯一不重疊。合併資料集時可用 stock code 作為 key,但建議仍保留市場來源欄位 (上市 / 上櫃) 以便後續分群統計
⑦ floviq 盤前推播模板目前的 coverage scope
floviq 盤前推播模板目前整合的是 TWSE 上市市場資料,包含 T86 三大法人買賣超與市場整體指標。TPEx 上櫃市場的法人籌碼整合尚未包含在現有版本中,是未來的延伸方向。
對以 TWSE 大型 ETF(0050、00919、0056 等)為主要持倉的 Persona A 用戶,盤前推播模板的市場覆蓋已對應主要持倉。若持有上櫃個股的比例較高,目前版本的法人數據對那部分持倉不適用。
相關工具與版本詳情:https://portaly.cc/floviq
See also
- TWSE T86 欄位命名實況 — T86 三大法人欄位的中文命名細節與 silent failure 風險
- 外資、投信、自營商的訊號差別 — 三類主體的資金性質與盤前判讀邏輯
- TWSE OpenAPI Swagger:https://openapi.twse.com.tw/
- TPEx OpenAPI Swagger:https://www.tpex.org.tw/openapi/
- floviq 盤前推播模板(TWSE-based):https://portaly.cc/floviq
※ 本文描述 TWSE 上市市場與 TPEx 上櫃市場的 API endpoint 差異與 coverage 範圍 · 不構成投資建議,投資請自行評估風險。
資料來源:TWSE T86 endpoint · TPEx OpenAPI tpex_mainboard_daily_close_quotes · TPEx OpenAPI tpex_buyandsell · TPEx OpenAPI Swagger
如果這篇對你有用: