Answer
How do you fetch Taiwan institutional investor flows? The TWSE T86 endpoint
Per-stock daily institutional flows come from the TWSE T86 endpoint. It needs no key and, unlike most open-data endpoints, it does accept a date parameter and returns the whole market for that trading day. The common mistake is summing the columns yourself: foreign investors and dealers are each split across sub-columns, so naive addition double-counts.
What the endpoint is
T86 is the Taiwan Stock Exchange's daily institutional-investor report, giving per-stock buy, sell and net volumes for foreign investors, investment trusts and dealers. Probed on 2026-07-31, a request for 2026-07-30 returned 13,262 rows and one for 2024-03-15 returned 16,051 — confirming it serves the requested date rather than only a latest snapshot.
curl "https://www.twse.com.tw/rwd/zh/fund/T86?date=20260730&selectType=ALL&response=json"How it differs from the open-data endpoints
Worth flagging: T86 belongs to the www.twse.com.tw report API, a different family from the openapi.twse.com.tw open-data endpoints. Those mostly serve the latest period only; T86 takes a date parameter, so you can walk backwards day by day. The response shape differs too — instead of a flat array you get an object with stat, date, fields and data, where the column names live in fields and the rows are a parallel two-dimensional array you zip together yourself.
The field trap: do not sum them yourself
This is where the numbers usually go wrong. The response carries 19 columns. Foreign investors are split into a mainland-and-foreign column excluding foreign dealers, plus a separate foreign-dealer column. Dealers are split into proprietary and hedging columns, alongside an already-aggregated dealer total. Adding every column that looks like foreign or dealer activity counts the same shares twice. For a total, use the official final column instead.
- Foreign net excluding foreign dealers, plus foreign-dealer net — these two together are the foreign total.
- Dealer net (proprietary) plus dealer net (hedging) — these equal the aggregated dealer net column.
- Investment trust net — a single column, no sub-parts.
- Three-institutional-investor net — the official aggregate; use this for totals.
Units are shares, not lots or currency
Every quantity is in shares. Taiwan market convention usually quotes lots of 1,000 shares, so divide if you want lots. The endpoint carries no monetary value, so a currency figure means joining the day's prices yourself.
Non-trading days say so explicitly
This is friendlier than most endpoints: probed on 2026-07-31, a request for Sunday 2026-07-26 came back with a stat field carrying a no-matching-data message and no rows, rather than silently returning the previous session. A scheduled job should check that stat is OK before writing, so an error message is never mistaken for an empty day.
import requests
def fetch_t86(date_yyyymmdd: str):
url = "https://www.twse.com.tw/rwd/zh/fund/T86"
params = {"date": date_yyyymmdd, "selectType": "ALL", "response": "json"}
payload = requests.get(url, params=params, timeout=30).json()
if payload.get("stat") != "OK":
return [] # non-trading day, or no matching data
fields = payload["fields"]
return [dict(zip(fields, row)) for row in payload["data"]]
rows = fetch_t86("20260730")
print(len(rows))When you need long history or both markets
T86 returns one day per call, so a multi-year series means iterating day by day and storing the results, while handling non-trading days, format changes and the OTC market separately (TPEx publishes its own endpoint with its own field names). TW Market Data's institutional flow dataset normalizes both markets into one schema, queryable by symbol and date range, with disclosed gaps preserved rather than filled.
curl "https://api.twmarketdata.com/v2/datasets/institutional-flow?symbol=2330&limit=10" \
-H "X-API-Key: <your key>"Related