「台股」對工程師抓資料的 trap:TWSE 和 TPEx 是兩個獨立市場
工程師或有程式底子的散戶在寫程式抓「台股」資料時,有一個常見的覆蓋盲點:直覺只打一個 TWSE(上市)endpoint,以為已覆蓋「台股全市場」,實際上漏掉整個 TPEx(上櫃)市場。台股並非單一交易所,而是由 TWSE 和 TPEx 兩個獨立機構、兩組獨立 API 組成。兩邊各有各的每日報價 endpoint、各有各的三大法人買賣超 endpoint,資料不互通。
本文整理兩市場的制度差異、API endpoint 對照,以及只抓 TWSE 的工具對哪類持倉會造成盲點。
① 台股 = 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 上游的欄位名 LatesAskPrice 本身就是拼錯的 · 對接時須照原樣使用,不可自行更正為 LatestAskPrice,否則欄位對不上,會靜默取不到值而不報錯)
上櫃三大法人買賣超(對應 TWSE T86)
GET https://www.tpex.org.tw/openapi/v1/tpex_3insti_daily_trading
提供上櫃市場外資(含陸資)、投信、自營商的逐檔買賣超資料,結構邏輯類似 TWSE T86,但是獨立的 endpoint,回傳的是 TPEx 掛牌股票的法人數據。其欄位採英文命名,例如 Foreign Investors include Mainland Area Investors (Foreign Dealers excluded)-Total Buy / SecuritiesInvestmentTrustCompanies-TotalBuy / Dealers-TotalBuy / TotalDifference,精確對應 T86 的外資 / 投信 / 自營商分類。筆數每日滾動,近期一次約九百多筆。
④ 為何抓資料容易誤判覆蓋範圍
抓資料時出現覆蓋盲點,有三個常見模式:
盲點 1:以為「台股 API」等於全市場
工程師搜尋「台股法人資料 API」,最先找到 TWSE 的 openapi.twse.com.tw,拿到 T86 回傳,看到有幾百筆股票資料,直覺認為「已經涵蓋台股」。實際上 TPEx 上櫃市場的個股近九百檔(另含 ETF / ETN / 權證等共破萬筆證券),完全不在 T86 的回傳裡,不是空陣列,而是根本不存在。
盲點 2:欄位命名差異造成橋接困難
TWSE T86 使用中文欄位名(如 外陸資買賣超股數(不含外資自營商)),TPEx 的 tpex_mainboard_daily_close_quotes 使用英文欄位名(如 SecuritiesCompanyCode)。兩市場的欄位語言不統一,若工程師習慣 TWSE 欄位後去接 TPEx,需要重新對照,不是直接替換。命名不一致也提高了靜默失敗的風險:拿 TWSE 的欄位名去解析 TPEx 回傳,不會報錯,只會拿到 undefined,若沒有做欄位驗證就會被靜默略過。
盲點 3:市場代表性混淆
財經新聞報導「外資昨日買超 XX 億」,指的通常是 TWSE 上市市場 T86 的外陸資合計。但聽到這個數字的散戶,若持有上櫃個股,這個「外資動向」並不包含他所持有標的的法人籌碼。兩個市場的法人數字是並排的兩份報告,不是一份。
⑤ 對上班族散戶持倉的盲點
持有 ETF 為主的上班族散戶,日常觀察的多為 TWSE 上市市場指標,0050、00919、0056 這類高股息或市值型 ETF 均掛牌於 TWSE,只抓 TWSE 的工具對這部分持倉的法人資料是完整的。
但在以下情況,只抓 TWSE 的工具會出現覆蓋缺口:
- 持有上櫃掛牌個股:部分中小型科技股、生技股掛牌於 TPEx,T86 不含這些股票的三大法人數據
- 持有成分股含上櫃股的 ETF:某些主題型 ETF(如特定生技 ETF)的成分股中包含上櫃個股,若工具只抓 TWSE 法人數據,對 ETF 的成分股分析是不完整的
- 比較市場間資金流動:若要觀察資金是否從上市轉移到上櫃(或反向),需要同時有兩個市場的法人數據才能計算
對資金主要放在 TWSE 大型 ETF 的散戶而言,這個盲點在日常操作層面影響有限;但對有部分上櫃持倉、又有程式底子的散戶,若程式只抓 TWSE 資料,上櫃部分的法人籌碼會是靜默缺漏而非明顯報錯,排查時不易察覺。
⑥ 同時抓兩市場的最小 endpoint 組合
若程式需要同時覆蓋上市與上櫃市場的三大法人資料,最小的 endpoint 組合如下:
// 上市三大法人(TWSE T86)
const twseUrl = `https://www.twse.com.tw/rwd/zh/fund/T86?date=${date}&selectType=ALL&response=json`;
// 上櫃三大法人(TPEx tpex_3insti_daily_trading · 逐檔,對應 T86)
const tpexUrl = `https://www.tpex.org.tw/openapi/v1/tpex_3insti_daily_trading`;
// 上市每日報價(TWSE openapi · 預設回傳最新交易日全市場資料)
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_3insti_daily_trading的欄位為英文命名,需對照 TPEx OpenAPI Swagger 確認(兩市場欄位結構不通用) - TWSE T86 需要帶
date參數;openapi.twse.com.tw 的 STOCK_DAY_ALL 與 TPEx endpoint 預設回傳最新一個交易日資料,不需帶日期。若需查詢歷史日期,建議以官方 OpenAPI Swagger 實測確認日期參數的行為 - 假日行為:TWSE T86 回傳
{"stat":"很抱歉,沒有符合條件的資料!","total":0}而非空陣列;注意stat訊息中的逗號為全形「,」(U+FF0C),以字串比對偵測假日時須以全形為準。TPEx 行為建議以 OpenAPI Swagger 實測確認 - 兩市場的股票代號由 TWSE / TPEx 統一以 ISIN 框架編碼,全市場唯一不重疊。合併資料時可用股票代號作為對應鍵,但建議仍保留市場來源欄位(上市 / 上櫃)以便後續分群統計
⑦ floviq 盤前推播模板目前的覆蓋範圍
floviq 盤前推播模板目前整合的是 TWSE 上市市場資料,包含 T86 三大法人買賣超與市場整體指標。TPEx 上櫃市場的法人籌碼尚未納入現有版本,是未來的延伸方向。
對以 TWSE 大型 ETF(0050、00919、0056 等)為主要持倉的用戶,盤前推播模板的市場覆蓋已對應主要持倉。若持有上櫃個股的比例較高,目前版本的法人數據對那部分持倉不適用。
相關工具與版本詳情:https://portaly.cc/floviq
See also
- TWSE T86 欄位命名實況 — T86 三大法人欄位的中文命名細節與靜默失敗風險
- 外資、投信、自營商的訊號差別 — 三類主體的資金性質與盤前判讀邏輯
- 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 差異與資料覆蓋範圍 · 不構成投資建議,投資請自行評估風險。
資料來源:TWSE T86 endpoint · TPEx OpenAPI tpex_mainboard_daily_close_quotes · TPEx OpenAPI tpex_3insti_daily_trading · TPEx OpenAPI Swagger
修正紀錄
先前版本有以下更正:
- §③:上櫃三大法人 endpoint
tpex_buyandsell→tpex_3insti_daily_trading - §③:上櫃三大法人分類「外資、投信、陸資」→「外資(含陸資)、投信、自營商」
- §⑥:T86 假日訊息
stat逗號 半形 → 全形「,」
如果這篇對你有用: