Building an AI agent? Start with /llms.txt for the full site index.
Market Structure & Reference
Trading calendar
Trading calendar
ReferenceSource: TWSE / TPEx·Plan: free·Cost: 1 credits·
GET /v2/datasets/trading-calendarTrading calendar is a Taiwan market dataset sourced from TWSE / TPEx, served by TW Market Data as GET /v2/datasets/trading-calendar.
Overview
Trading calendar — grain: trade_date / market.
| Field | Type | Description |
|---|---|---|
trade_date | string | |
market | string | |
is_trading_day | boolean | |
calendar_source | string | |
derived_from_price | boolean | |
price_coverage_count | number | |
source_confidence | string | |
data_gap_reason | string | |
closure_reason | null |
Example response
A real response from this endpoint. Rows are returned under "data", and provenance is carried in the shape shown below — it is not identical across datasets, so read this page's rather than assuming another's.
{ "dataset_id": "trading_calendar", "request_context": { "scope": "twse_tpex_trading_day_calendar", "coverage_type": "daily", "filters": { "market": null, "trade_date": "2026-08-05", "date_from": null, "date_to": null, "limit": 50 }, "min_trade_date": "2026-08-05", "max_trade_date": "2026-08-05" }, "quality": { "row_count": 2, "trading_day_count": 2, "non_trading_day_count": 0, "derived_from_price_count": 2, "markets_present": [ "TPEx", "TWSE" ], "sensitive_fields_exposed": false }, "lineage": { "calendar_sources": [ "derived_from_price_observations" ], "semantics": "One row per (trade_date, market) recording whether the market traded. DERIVED from observed price rows; price_coverage_count is how many securities were seen trading that day, which is the evidence behind is_trading_day." }, "error": null, "data": [ { "trade_date": "2026-08-05", "market": "TPEx", "is_trading_day": true, "calendar_source": "derived_from_price_observations", "derived_from_price": true, "price_coverage_count": 1012, "source_confidence": "high", "data_gap_reason": "official_calendar_not_integrated;derived_from_observed_price_rows", "closure_reason": null }, { "trade_date": "2026-08-05", "market": "TWSE", "is_trading_day": true, "calendar_source": "derived_from_price_observations", "derived_from_price": true, "price_coverage_count": 1377, "source_confidence": "high", "data_gap_reason": "official_calendar_not_integrated;derived_from_observed_price_rows", "closure_reason": null } ], "data_count": 2, "known_gaps": [ "derived_from_observed_price_rows_not_an_official_exchange_calendar", "future_dates_have_no_row_absence_is_not_a_declared_holiday", "closure_reason_is_populated_only_where_a_reason_was_recoverable" ], "warnings": [ "not_investment_advice" ], "envelope": { "dataset_id": "trading_calendar", "scope": "twse_tpex_trading_day_calendar", "row_count": 2 }}Captured from the live API on 2026-07-20.
Getting started
- Put your key in the X-API-Key header.
- Add query parameters (symbol, date range, limit).
- Send the request and read the data array.
curl "https://api.twmarketdata.com/v2/datasets/trading-calendar?symbol=2330" \ -H "X-API-Key: sk_live_..."Filtering
| Parameter | Required | Type | Description |
|---|---|---|---|
symbol | No | string | Ticker to filter to a single security. |
limit | No | integer | Maximum rows to return. |
Python
A first call:
import requests resp = requests.get( "https://api.twmarketdata.com/v2/datasets/trading-calendar", params={"symbol": "2330"}, headers={"X-API-Key": "sk_live_..."},)resp.raise_for_status()print(resp.json()["data"])With a date-range filter:
import requests # The full verified example — the same call with every supported filter set.resp = requests.get( "https://api.twmarketdata.com/v2/datasets/trading-calendar", params={"symbol": "2330"}, headers={"X-API-Key": "sk_live_..."},)resp.raise_for_status()for row in resp.json()["data"]: print(row)OpenAPI
This endpoint is GET /v2/datasets/trading-calendar. The full machine-readable schema (parameters, security, response envelope) lives in the OpenAPI spec.
Notes & limitations
- Future trading days come from the officially published calendar and are known in advance, so this is PIT-safe. But the table is derived from actual price rows: a missing future date means 'no evidence yet', NOT 'declared closed'. max(trade_date) must not be read as staleness.