How do I tell whether Taiwan market data is missing something?
Separate two things: the market was closed, and the data did not arrive. For prices, the response's meta.market_status tells you which dates were open, so you can compare that against the rows you received. Some datasets carry a per-row data_gaps field; the price endpoint does not, and instead gives you price_method and price_confidence describing how each number was produced.
Two kinds of missing, handled differently
- The market was closed: weekends, public holidays, typhoon days. Not a gap — your series should not have those dates.
- The data did not arrive: the market traded and you have no row. That is a gap, and left unhandled it quietly distorts calculations.
- Conflating the two usually ends in forward-filling, which invents a flat day that never happened.
Prices: use meta.market_status to separate closed from missing
The price response's meta carries last_trading_day and market_status, a list of date and status pairs where status is open or unknown. Open means the market traded; unknown means not yet determined. Compare that against the dates you received and the distinction resolves itself.
import requests
r = requests.get(
"https://api.twmarketdata.com/v2/datasets/twse-daily-price",
headers={"X-API-Key": "sk_live_your_key"},
params={"symbol": "2330", "start_date": "2026-06-01", "end_date": "2026-07-31"},
timeout=20,
)
r.raise_for_status()
payload = r.json()
print("rows", payload["count"], "data as of", payload["data_as_of"])
print("last trading day", payload["meta"]["last_trading_day"])
have = {row["date"] for row in payload["rows"]}
for entry in payload["meta"]["market_status"]:
if entry["status"] == "open" and entry["date"] not in have:
print("market traded but no row:", entry["date"])Every price row explains how it was produced
Each row carries price_method and price_confidence. When a value looks odd or a stretch is uncertain, read those two before deciding whether to use it — they tell you more about trustworthiness than the close itself does.
for row in payload["rows"][:5]: print(row["date"], row["close"], "method", row["price_method"], "confidence", row["price_confidence"])Some datasets carry data_gaps, and it is per row
Margin and short balance data, for instance, carries a data_gaps field on every row. In practice it is usually an empty list, meaning no known gap for that row; when populated it describes that row's gaps. Note that it is per row, not one summary for the response.
m = requests.get( "https://api.twmarketdata.com/v2/datasets/margin-short", headers={"X-API-Key": "sk_live_your_key"}, params={"symbol": "2330", "limit": 20}, timeout=20,).json() for row in m["rows"]: if row["data_gaps"]: print(row["trade_date"], "gap markers:", row["data_gaps"])Elsewhere data_gaps describes the dataset, not a day
On some datasets the same name holds named coverage limitations rather than dates — statements about what the dataset never covered, such as being limited to the listed market. That is not telling you a day is missing; it is telling you a scope boundary exists, which is worth reading before any cross-market analysis.
There is no single site-wide gaps field
Worth saying plainly: data_gaps is not present on every endpoint. The price endpoint has none, and offers market_status, count, data_as_of and per-row price_method and price_confidence instead. So the right move is not to hunt for data_gaps, but to check which signal the endpoint you are calling actually provides.
Whatever the signal, do not patch the hole yourself
- Do not forward-fill. It manufactures a flat session, understating volatility and hiding drawdown.
- Do not substitute zero. Zero is meaningful in prices and in net flow, so afterwards you cannot distinguish 'was zero' from 'was absent'.
- Leave the gap and skip it explicitly in calculations. A series repaired to look complete will flatter a backtest — the same problem as look-ahead, one layer down.
What we do not have
- No uniform data_gaps field across all datasets, as above.
- No real-time quotes, so an intraday missing tick is out of scope here — the day's data exists after the close.
- In market_status, unknown means undetermined, not closed. Do not treat it as a holiday.
Common questions
1I asked for a month and got 43 rows. Did I lose some?
2data_gaps is an empty list. Does that mean the data is perfect?
3Why not just fill the gaps for me?
4Why does the price endpoint have no data_gaps?
Want to query this data yourself? Create a free account.