三大法人買賣超資料有哪些陷阱?

三個:一、不要自己用「買進減賣出」算淨額,那兩個欄位可能是空的,直接用 foreign_net_buy_sell 這類淨額欄位。二、上市與上櫃是兩套資料,加總前先看 market 欄位,否則同一個概念會被算兩次。三、當天的數字不一定是最終版,用 updated_at 判斷你手上這筆是什麼時候寫進去的。

三大法人

外資(及陸資)、投信、自營商,台股每日盤後公布的三種機構買賣超;資料來自 TWSE T86。

陷阱一:買賣兩腳可能是空的,淨額欄位才是你要的

回應同時有「買進」「賣出」與「淨額」三組欄位,但買賣兩腳不保證有值——實際取回的列裡,foreign_buy 與 foreign_sell 都是 null,而 foreign_net_buy_sell 有值。如果你習慣自己算 buy − sell,得到的會是 0,或直接在 None 上做減法炸掉。要淨額就讀淨額欄位。

import requests

r = requests.get(
"https://api.twmarketdata.com/v2/datasets/institutional-flow",
headers={"X-API-Key": "sk_live_你的金鑰"},
params={"symbol": "1301", "start_date": "2026-08-01", "end_date": "2026-08-04"},
timeout=20,
)
r.raise_for_status()

for row in r.json()["rows"]:
print(row["date"], row["market"],
"外資淨額", row["foreign_net_buy_sell"],
"| 買進腳", row["foreign_buy"], "賣出腳", row["foreign_sell"])
# 買賣兩腳可能是 None:先確認再用,不要直接相減

三個淨額相加會等於合計,可以拿來自我檢查

外資、投信、自營商三個淨額加起來,等於 total_institutional_net_buy_sell。實際資料上兩列都完全吻合。這給你一個免費的健檢:如果你的管線算出來對不上,那是你的處理出了問題,不是資料。

for row in r.json()["rows"]:    parts = (row["foreign_net_buy_sell"], row["investment_trust_net_buy_sell"], row["dealer_net_buy_sell"])    if None not in parts and sum(parts) != row["total_institutional_net_buy_sell"]:        print("對不上:", row["date"], sum(parts), row["total_institutional_net_buy_sell"])

陷阱二:上市與上櫃加總會重複計

每一列都有 market 欄位(TWSE 或 TPEx)。上市與上櫃是兩套獨立公布的資料,如果你把一段期間的所有列直接 sum(),同一個概念會被算兩次,「全市場買超」就會偏高。要算單一市場先過濾 market;要算全市場,先確認沒有同一 symbol 同一 date 出現兩列。

rows = r.json()["rows"] twse_only = [x for x in rows if x["market"] == "TWSE"] # 加總前先驗有沒有重複的 (symbol, date)seen = set()for x in rows:    key = (x["symbol"], x["date"], x["market"])    if key in seen:        print("重複列:", key)    seen.add(key)

陷阱三:當天的數字不一定是最終版

盤後定價與鉅額配對等交易,可能在首次公布之後才被補進來,所以某一天的買賣總量事後會略為變動。回應裡每一列都帶 updated_at(這筆最後寫入的時間)與 as_of_date(資料所屬日)。要判斷手上這筆是不是剛出爐、值不值得等一天再定案,看這兩個欄位,而不是憑感覺。

for row in r.json()["rows"]:    print(row["date"], "資料日", row["as_of_date"], "最後更新", row["updated_at"])    # 資料日與最後更新差得很近  很可能還會被補;差了一兩天以上通常已經穩定

子分類不在這支回應裡

如果你的分析要分到「自營商自行買賣 vs 避險」或「外資自營」這種子分類,這支回應沒有——它給的是外資、投信、自營商三組的合計。需要子分類就回官方來源取。用同一組合計定義跑完整段歷史,至少跨期是一致的。

每一列都帶來源,可以逐筆回推

回應帶 provider、source_role 與 lineage。實際取到的列上,source_role 是 official_twse_t86,lineage 裡記著 endpoint_name「T86」與 source_authority「TWSE T86」,還有那筆的來源日期。要跟官方對帳時,這是你的憑據。

我們沒有的東西,先說清楚

  • 沒有即時法人買賣。這是盤後資料,收盤後才公布,盤中查不到當天的數字。
  • 沒有一個欄位直接告訴你「這筆已定案」。updated_at 與 as_of_date 是你判斷的依據,不是官方的定案旗標——官方本身沒有固定的定案時點。
  • 買賣兩腳在實際資料中可能是空值,如上。淨額欄位才是可靠的那組。

常見問題

1為什麼我算的全市場買超總是偏高?
多半是把上市與上櫃兩套資料加在一起了。先用 market 欄位分開,或先檢查有沒有同一 symbol 同一 date 出現兩列。
2買進和賣出欄位是空的,是資料壞了嗎?
不是。淨額欄位才是這支保證會給的那組,買賣兩腳不一定有值。要買賣超就讀 foreign_net_buy_sell、investment_trust_net_buy_sell、dealer_net_buy_sell,三者相加會等於 total_institutional_net_buy_sell。
3當天收盤後馬上抓,數字會再變嗎?
有可能。盤後定價與鉅額配對等交易會在首次公布之後補進來。用 updated_at 看這筆最後寫入的時間;要穩一點就隔一兩天再回頭覆核同一天的數字。
4這跟回測有什麼關係?
有。如果你用「當天盤後抓到的版本」做回測,而實際上那個數字後來被補過,你的回測就用到了一個當時還不是最終版的值。這跟前視偏誤是同一類問題——歷史被事後改過。

想自己查這些資料?免費註冊

相關文章