Taiwan Futures & Options API

12 endpoints

Last updated 2026-10
Base URL
https://api.blave.org
Auth
api-key + secret-key headers on every request
Access
API plan or data fee
Rate Limit
500 requests / 5 min per key and per IP

Taiwan Futures OHLCV

GET/studio/market/twfutures/ohlcv/<symbol>/<schema>
Data From
TXF: 2011-01-03 (1d and intraday). MXF: 2020-03-22 (1d). Stock futures start per contract — CAF returned 1d bars at least as early as 2016-09-18 (the probe window began there, so it may reach further back)
Update
Near-real-time from the on-disk 1m store, refreshed on request
Source
Sinopac Shioaji (near-month continuous series)

Parameters

symbolstringpathRequired
Near-month continuous contract
Allowed TXF (台指期), MXF (小台), or a stock-futures id listed by ohlcv/symbols (case-insensitive)
schemastringpathRequired
Bar size
Allowed 1m, 5m, 15m, 30m, 60m, 1d
startstringquery
First day
Default end − the schema's max rangeAllowed YYYY-MM-DD
endstringquery
Last day
Default today (UTC)Allowed YYYY-MM-DD

Max range per request (end − start): 1m 31 d · 5m 62 d · 15m 93 d · 30m 186 d · 60m 365 d · 1d 3650 d.

Example

Response

{"symbol", "schema", "data": [...]}.

FieldTypeUnitDescription
tsstringUTC ISOBar open time
open / high / low / closefloatindex points (price for stock futures)Prices
volumeintcontracts (口)Volume

Errors

StatusBodyWhen
400{"error": "Invalid symbol. Allowed: [...]"}Symbol not covered
400{"error": "Invalid schema. Allowed: [...]"}Bad schema
400{"error": "Invalid date format. Use YYYY-MM-DD"}Malformed date
400{"error": "date_range_too_large", "message": "...", "max_days": <n>}Range over the cap
503error messageData source temporarily unavailable

Notes

  • Intraday bars before 2017-05-15 are day session only (the night session 15:00–05:00 Taipei launched then), so bars per day jump from ~300 to ~1,140 at that date.
  • The series rolls contracts at monthly settlement without price adjustment — mask the roll in backtests.
  • Roll rule (all schemas; TXF, MXF, and stock futures alike): monthly settlement day — the 3rd Wednesday, or the next trading day when that Wednesday is closed — is the expiring month for the whole day. It trades through its 13:30 Taipei close, no bar is stamped 13:31–14:59 Taipei on that day, and the series is the next month from the 15:00 night session on. The settlement day's 1d bar is the expiring month's, so its close is that contract's last trade at 13:30.
  • For years of history use ohlcv/<symbol>/export/<year> instead of chunked JSON.
  • A range with no data returns 200 with [].
  • Do not assume the series runs to the last trading day — MXF and CAF asked for everything up to the request date both came back with a last bar months old. Read data[-1]["ts"].
  • 1d bars carry a 16:00:00+00:00 time component (00:00 Taipei), not midnight UTC — take the date from ts rather than assuming the timestamp is date-aligned.

Taiwan Futures Minute-Line Symbols

GET/studio/market/twfutures/ohlcv/symbols
Data From
Snapshot
Update
Live
Source
Blave

Parameters

None.

Example

Python
symbols = requests.get(f"{BASE_URL}/studio/market/twfutures/ohlcv/symbols", headers=headers, timeout=30).json()["data"]

Response

{"data": ["CDF", "DHF", "MXF", "TXF", ...]} — symbols accepted by ohlcv, ohlcv/export, and bid_ask_vol: TXF, MXF, plus the liquidity-picked subset of stock futures with minute-line coverage (most of the 231 stock futures are not covered).

Errors

Shared errors only.

Taiwan Futures 1m Yearly Export

GET/studio/market/twfutures/ohlcv/<symbol>/export/<year>
Data From
2011 (TXF)
Update
Past years immutable; the current year's file is refreshed before download
Source
Sinopac Shioaji

Parameters

symbolstringpathRequired
Symbol
Allowed As ohlcv/symbols
yearintpathRequired
Calendar year
Allowed 2014 – current year

Example

Python
import ioimport pandas as pdr = requests.get(f"{BASE_URL}/studio/market/twfutures/ohlcv/TXF/export/2024", headers=headers, timeout=120)raw = pd.read_parquet(io.BytesIO(r.content))raw.index = pd.to_datetime(raw["ts"], utc=True)bars_60m = (raw[["open", "high", "low", "close", "volume"]]            .resample("60min")            .agg(open=("open", "first"), high=("high", "max"), low=("low", "min"),                 close=("close", "last"), volume=("volume", "sum"))            .dropna(subset=["open"]))

Response

application/octet-stream, a parquet file (<SYMBOL>_<year>_1m.parquet) with columns ts, open, high, low, close, volume (1m bars).

Errors

StatusBodyWhen
400{"error": "Invalid symbol. Allowed: [...]"}Symbol not covered
400{"error": "Invalid year. Allowed: 2014-<current>"}Year out of range
404{"error": "no_data", "message": "No 1m data on disk for <symbol> in <year>"}No file

Notes

  • One request per year, zero server-side computation — resample locally.
  • Same near-month continuous series as ohlcv/<symbol>/1m, under the same settlement-day roll rule (no bars stamped 13:31–14:59 Taipei on monthly settlement day).

Taiwan Futures Bid/Ask Volume

GET/studio/market/twfutures/bid_ask_vol/<symbol>
Data From
2018-02-22 (TXF)
Update
Aggregated from ticks, refreshed on request
Source
Tick data (Sinopac Shioaji)

Parameters

symbolstringpathRequired
Symbol
Allowed TXF, MXF (both verified to return data); other ohlcv/symbols ids untested
startstringquery
First day
Default end − 31 daysAllowed YYYY-MM-DD
endstringquery
Last day; end − start ≤ 31 days
Default today (UTC)Allowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/bid_ask_vol/TXF", headers=headers,                    params={"start": "2026-05-29", "end": "2026-05-29"}, timeout=60).json()["data"]# [{"ts": "2026-05-29 00:45:00+00:00", "bid_vol": 669, "ask_vol": 447, "total_vol": 1156}, ...]

Response

{"symbol", "start", "end", "data": [...]}, 1-minute rows, day and night sessions.

FieldTypeUnitDescription
tsstringUTC ISOBar open time
bid_volintcontracts內盤 — trades hitting the bid (seller-initiated)
ask_volintcontracts外盤 — trades lifting the ask (buyer-initiated)
total_volintcontractsTotal, including unclassified ticks

Errors

StatusBodyWhen
400{"error": "Invalid symbol. Allowed: [...]"}Symbol not covered
400{"error": "Invalid date format. Use YYYY-MM-DD"}Malformed date
400{"error": "date_range_too_large", "message": "...", "max_days": 31}Range over 31 days
503error messageData source temporarily unavailable

Notes

  • Rows are the near-month continuous contract under the same roll rule as ohlcv: on monthly settlement day there are no rows between the expiring month's 13:30 Taipei close and the 15:00 night open; from the night session on the rows are the next month.

Taiwan Futures Daily by Contract

GET/studio/market/twfutures/daily/<futures_id>
Data From
1998-07-21 for TX; other products start later — MTX from 2001-04-09, CDF (stock futures) from 2010-01-25
Update
Daily after ~15:00 Taipei (TAIFEX direct before FinMind catches up); server cache 5 min
Source
FinMind TaiwanFuturesDaily; TAIFEX (latest day for TX / MTX / TMF)

Parameters

futures_idstringpathRequired
Product
Allowed 2–6 letters, case-insensitive — e.g. TX, MTX, TMF, TE, TF, or a stock-futures id (e.g. CDF)
startstringquery
First date
Default 1998-07-01Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/daily/TX", headers=headers,                    params={"start": "2026-08-01"}, timeout=60).json()["data"]

Response

{"futures_id", "data": [...]}; several rows per day (every contract month × trading session).

FieldDescription
date, futures_idDay, product
contract_dateContract month (spread contracts contain /)
open / max / min / closePrices (max = high, min = low)
spread / spread_perChange / change %
volumeContracts
settlement_priceSettlement price
open_interestOpen interest
trading_sessionposition (regular) or after_market (night)

Errors

StatusBodyWhen
400{"error": "Invalid futures_id"}Format check failed
404{"error": "No data found for futures_id: <id>"}No data
503{"error": "Upstream rate limit. Please retry shortly."}Upstream quota exhausted

Stock Futures Batch Daily

GET/studio/market/twfutures/stock_futures/batch/daily
Data From
Per contract listing — CDF asked from 1998-07-01 returned rows starting 2010-01-25
Update
As /daily/<futures_id>
Source
As /daily/<futures_id>

Parameters

futures_idsstringqueryRequired
Ids
Allowed Comma-separated stock-futures ids, ≤ 250
startstringquery
First date
Default 1998-07-01Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
body = requests.get(f"{BASE_URL}/studio/market/twfutures/stock_futures/batch/daily", headers=headers,                    params={"futures_ids": "CDF,DHF", "start": "2026-08-01"}, timeout=120).json()

Response

{"data": {"<futures_id>": [...rows as /daily...]}, "failed": [...]}. failed = ids whose fetch failed (retry); an id absent from both genuinely has no data.

Errors

StatusBodyWhen
400{"error": "futures_ids parameter required"}Missing
400{"error": "futures_ids exceeds max 250 per request"}Too many
400{"error": "Invalid stock futures_id(s): [...]"}Any id is not a stock future
503{"error": "Stock futures symbol list temporarily unavailable. Please retry shortly."}Symbol list unavailable

Taiwan Futures Institutional Investors

GET/studio/market/twfutures/institutional/<futures_id>
Data From
2018-06-05
Update
Daily after ~15:00 Taipei (TAIFEX direct before FinMind catches up); server cache 5 min
Source
FinMind TaiwanFuturesInstitutionalInvestors; TAIFEX (latest day)

Parameters

futures_idstringpathRequired
Product
Allowed Index futures — TX, MTX, TMF, TE, TF (all verified to return data); stock futures not supported
startstringquery
First date
Default 2018-06-05Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/institutional/TX", headers=headers,                    params={"start": "2026-08-01"}, timeout=60).json()["data"]

Response

{"futures_id", "data": [...]}, 3 rows per day (自營商 / 投信 / 外資).

FieldDescription
date, futures_idDay, product
institutional_investorsInvestor type
long_deal_volume / long_deal_amountLong trades (contracts / TWD thousand)
short_deal_volume / short_deal_amountShort trades
long_open_interest_balance_volume / long_open_interest_balance_amountLong OI
short_open_interest_balance_volume / short_open_interest_balance_amountShort OI

Errors

StatusBodyWhen
400{"error": "Invalid futures_id"}Format check failed
404{"error": "institutional data not available for stock futures (<id>)"}Stock future
404error messageNo data
503upstream rate limit / symbol list unavailableRetry later

Notes

  • *_amount is TWD thousand — inferred from magnitude, not stated upstream, but the arithmetic backs it: a TX row with long_open_interest_balance_amount 722870036 over ..._volume 78292 is 9,233 per contract, and a TX contract is index × 200, so 9,233 thousand ÷ 200 ≈ 46,160 index points, which is where the index was trading that day. Read as TWD it would be 1,000× too small.

Taiwan Futures Large Traders

GET/studio/market/twfutures/large_traders/<futures_id>
Data From
2007-01-02 — TX asked from 1998-07-01 returned nothing before that date
Update
Daily; server cache 5 min
Source
FinMind TaiwanFuturesOpenInterestLargeTraders

Parameters

futures_idstringpathRequired
Product
Allowed Index futures, e.g. TX; stock futures not supported
startstringquery
First date
Default 1998-07-01Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/large_traders/TX", headers=headers,                    params={"start": "2026-08-01"}, timeout=60).json()["data"]

Response

{"futures_id", "data": [...]}, 3 rows per day (contract_type: week / current month / all).

FieldDescription
date, futures_id, name, contract_typeDay, product, product name, contract scope
buy_top5_trader_open_interest / buy_top10_trader_open_interest (+ _per)Long OI of top 5 / 10 traders (contracts, % of market)
sell_top5_trader_open_interest / sell_top10_trader_open_interest (+ _per)Short OI of top 5 / 10 traders
buy_top5_specific_open_interest / buy_top10_specific_open_interest (+ _per)Long OI of top 5 / 10 specific legal persons
sell_top5_specific_open_interest / sell_top10_specific_open_interest (+ _per)Short OI of top 5 / 10 specific legal persons
market_open_interestTotal market OI

Errors

StatusBodyWhen
400{"error": "Invalid futures_id"}Format check failed
404{"error": "large_traders data not available for stock futures (<id>)"}Stock future
404error messageNo data
503upstream rate limit / symbol list unavailableRetry later

Taiwan Options Institutional Investors

GET/studio/market/twfutures/option/institutional/<option_id>
Data From
2018-06-05
Update
Daily; server cache 5 min
Source
FinMind

Parameters

option_idstringpathRequired
Option product
Allowed TXO (2–6 letters accepted)
startstringquery
First date
Default 2018-06-05Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/option/institutional/TXO", headers=headers,                    params={"start": "2026-08-01"}, timeout=60).json()["data"]

Response

{"option_id", "data": [...]}, 6 rows per day (3 investor types × call / put). Fields: date, option_id, call_put (買權 / 賣權), institutional_investors, and the same long_* / short_* deal and open-interest volume / amount fields as futures institutional.

Errors

400 {"error": "Invalid option_id"}; 404 no data; 503 upstream rate limit.

Taiwan Options Large Traders

GET/studio/market/twfutures/option/large_traders/<option_id>
Data From
2007-01-02 — TXO asked from 1998-07-01 returned nothing before that date
Update
Daily; server cache 5 min
Source
FinMind

Parameters

option_idstringpathRequired
Option product
Allowed TXO (2–6 letters accepted)
startstringquery
First date
Default 1998-07-01Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/option/large_traders/TXO", headers=headers,                    params={"start": "2026-08-01"}, timeout=60).json()["data"]

Response

{"option_id", "data": [...]}, 6 rows per day (call / put × week / current month / all). Fields: date, option_id, name, put_call, contract_type, and the same top-5 / top-10 trader and specific-legal-person open-interest fields as futures large traders, plus market_open_interest.

Errors

400 {"error": "Invalid option_id"}; 404 no data; 503 upstream rate limit.

TXO Put/Call Ratio

GET/studio/market/twfutures/option/pcr
Data From
2001-12-24
Update
Daily; server cache 5 min
Source
TAIFEX pcRatio (official)

Parameters

startstringquery
First date
Default 2001-12-24Allowed YYYY-MM-DD
endstringquery
Last date
Default todayAllowed YYYY-MM-DD

Example

Python
data = requests.get(f"{BASE_URL}/studio/market/twfutures/option/pcr", headers=headers,                    params={"start": "2024-01-01", "end": "2024-12-31"}, timeout=60).json()["data"]# [{"date": "2024-01-02", "put_volume": 309583, "call_volume": 404231, "volume_pcr": 76.59,#   "put_oi": 263673, "call_oi": 246495, "oi_pcr": 106.97, "pcr": 106.97},#  {"date": "2024-01-03", "put_volume": 622854, "call_volume": 729547, "volume_pcr": 85.38,#   "put_oi": 177203, "call_oi": 178062, "oi_pcr": 99.52, "pcr": 99.52}, ...]

Response

{"data": [...]}, one row per trading day.

FieldUnitDescription
date—Trading day
put_volume / call_volumecontractsPut / call volume
volume_pcr%Put/call volume ratio
put_oi / call_oicontractsPut / call open interest
oi_pcr%Put/call open-interest ratio (買賣權未平倉量比率)
pcr%Same as oi_pcr (kept for compatibility)

Errors

404 no data; 503 store not ready or upstream rate limit.

Notes

  • The official TAIFEX ratio — not derived from option institutional or large-trader data.

Taiwan Index Futures Institutional Carrying Cost

GET/studio/market/twfutures/carrying_cost/<identity>
Data From
2023-10-18 (TAIFEX publishes only about the last three years)
Update
Daily after TAIFEX publishes — Blave jobs at 15:40 and 17:40 Taipei; server cache 5 min
Source
Blave estimate from TAIFEX data only: 三大法人-區分各期貨契約 (TX / MTX / TMF) and 期貨每日交易行情 (TX close)

Blave's estimate of the average cost of one institution's net TAIEX-futures position, with its unrealized and realized PnL. An estimate from daily aggregates, not the institution's real fills.

Method:

  • Position = long OI − short OI, converted to 大台 (TX) contracts: TX × 1, MTX × 1/4, TMF × 1/20 (scope=all), or TX only (scope=tx).
  • Adding to the position uses that institution's own average trade price of the day on the side it added (TAIFEX 交易契約金額 ÷ (口數 × 200)) and updates a weighted-average cost. Reducing books realized PnL at the opposite side's average price and leaves the cost unchanged. A flip, or going flat, realizes the whole old position; the new direction starts at that day's price.
  • Every monthly settlement day (third Wednesday; the next trading day if closed) starts a new cycle: cost resets to the mark price and realized PnL to 0. This makes the cost independent of where the data starts.
  • Mark price = TAIFEX's own valuation of the open position (OI contract value ÷ (contracts × 200), i.e. at each month's settlement price). Unrealized PnL = (mark − cost) × net contracts × 200.

Parameters

identitystringpathRequired
外資 / 投信 / 自營商
Allowed foreign, investment_trust, dealer
startstringquery
First trading date, inclusive
Default 2023-10-18 (whole history)Allowed YYYY-MM-DD
endstringquery
Last trading date, inclusive
Default todayAllowed YYYY-MM-DD
scopestringquery
all = TX + MTX + TMF in TX-equivalent contracts; tx = 大台 only (the basis most Taiwanese sites quote)
Default allAllowed all, tx

The ledger always runs from the start of the stored history; start / end only cut the window, so the same day has the same values whatever window you ask for.

Example

Python
body = requests.get(f"{BASE_URL}/studio/market/twfutures/carrying_cost/foreign", headers=headers,                    params={"start": "2026-10-06"}, timeout=60).json()rows = body["data"]# Live capture 2026-10-07 (scope=all):# {"identity": "foreign", "scope": "all", "data": [#   {"date": "2026-10-06", "net_open_interest": -78570.7, "net_open_interest_change": -3923.5,#    "cost": 46527.57, "txf_close": 50060.0, "mark_price": 50088.51,#    "unrealized_pnl": -55957022956, "realized_pnl": -5893982992, "total_pnl": -61851005948,#    "cycle_start": "2026-09-16"},#   {"date": "2026-10-07", "net_open_interest": -78435.8, "net_open_interest_change": 134.9,#    "cost": 46527.57, "txf_close": 49979.0, "mark_price": 49974.38,#    "unrealized_pnl": -54070636128, "realized_pnl": -5988669182, "total_pnl": -60059305310,#    "cycle_start": "2026-09-16"}]}gap = rows[-1]["txf_close"] - rows[-1]["cost"]   # points the market is above (+) / below (−) their cost

Response

{"identity", "scope", "data": [...]}, one row per trading day, oldest → newest; "stale": true is added only when the server's copy is behind TAIFEX's last published day (the newest row may be missing).

FieldTypeUnitDescription
datestring—Trading day (Taipei)
net_open_interestfloatTX-equivalent contractsLong − short OI (negative = net short)
net_open_interest_changefloatcontractsChange vs the previous trading day
costfloat | nullindex pointsWeighted-average cost of the net position; null when flat
txf_closefloat | nullindex pointsTX near-month day-session close (the expiring contract is skipped on settlement day)
mark_pricefloat | nullindex pointsTAIFEX valuation of the position, at settlement prices
unrealized_pnlintTWD(mark − cost) × net contracts × 200
realized_pnlintTWDRealized since cycle_start; resets to 0 on every settlement day
total_pnlintTWDunrealized_pnl + realized_pnl
cycle_startstring—The settlement day that opened the current cycle

Errors

StatusBodyWhen
400{"error": "Invalid identity. Allowed: ['dealer', 'foreign', 'investment_trust']"}Unknown identity
400{"error": "Invalid scope. Allowed: ['all', 'tx']"}Unknown scope
400{"error": "Invalid start date, expected YYYY-MM-DD"} (or end) / {"error": "start must not be after end"}Bad date / reversed range
503{"error": "Market data is not ready on this server. Please retry later."}Store not ready — retry later, never read as "no position"
500{"error": "Internal error"}Unexpected server error

Notes

  • Futures only: option positions (including dealers' hedges) are not in the ledger, so a dealer's "loss" here may be offset elsewhere.
  • Right after a settlement day the cost equals the mark by construction — the first days of a cycle say little about where the position was really built.
  • Other sites' 外資成本 figures use different rules (TX only, near-month close as the trade price, or undisclosed) — numbers will differ; compare like with like (scope=tx).