# Taiwan Stock Daily Quotes — 台股行情 OHLCV API (`chamarix/taiwan-stock-daily-quotes`) Actor

Daily OHLCV for every security on the Taiwan Stock Exchange and Taipei Exchange, with P/E, price-to-book and dividend yield joined on. TWSE reaches back to 2004-02-11, TPEX to 2007-07-02. Ex-rights sessions are flagged, not silently mispriced.

- **URL**: https://apify.com/chamarix/taiwan-stock-daily-quotes.md
- **Developed by:** [chris](https://apify.com/chamarix) (community)
- **Categories:** AI, Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Taiwan Stock Daily Quotes (台股每日行情) API

Get structured JSON access to **daily OHLCV for every security in Taiwan** — around **1,380 on the TWSE and 1,010 on the TPEX** in a single session, each with open, high, low, close, change, volume, turnover and trade count, plus **P/E, price-to-book and dividend yield** joined on from the exchanges' own valuation reports. TWSE sessions go back to **2004-02-11**, TPEX to **2007-07-02**.

This is the price series everything else keys off. Whatever you are doing with Taiwan market data — margin balances, institutional flow, shareholding dispersion, revenue surprises — it has to be aligned to a price, and the price has to be right on the two days a year where it is easy to get wrong: the ex-dividend days. Each exchange marks those differently, one of them does not mark them at all, and none of it is documented. This Actor resolves all three conventions into one field you can trust.

### Why this data matters

- **Ex-rights sessions are flagged, not silently mispriced.** On 2026-06-11 TSMC closed at 2,250.00 against a previous close of 2,255.00 — but the exchange printed the change as `X0.00`, because the stock went ex-dividend that morning. The `X` means *not comparable to the previous close*; the `0.00` beside it carries no information at all. Read that column as a number and you have recorded TSMC as unchanged on a day it moved. Here it comes back as `change: null`, `change_basis: "PRICE_NOT_COMPARABLE"`.
- **TPEX's per-security report has no marker at all**, and prints a change measured against the ex-rights reference price. 中美晶 5483 on 2026-07-23: previous close 234.00, close 212.50, printed change −19.00. Neither number is wrong; they are measured from different bases. The Actor detects the gap, sets `change_basis: "EX_RIGHTS_REFERENCE"`, and gives you the reference price it was measured from. *Verified against the official dividend:* 5483's two 2026 ex-rights sessions imply deductions of 1.00 and 2.50, summing to exactly the **3.50 per share** TPEX publishes for that dividend year.
- **Every row carries its own identity checks.** `ohlc_consistent` proves low ≤ open, close ≤ high. `average_price_in_range` puts turnover ÷ volume inside the day's band. `change` is checked against the previous session's close wherever the run has seen it — across 465 TWSE sessions in 2026 for 2330, 1101 and 2317, that identity held **to the cent, every time**, and the days it did not apply were exactly the four ex-rights days the official 除權息計算結果 report lists.
- **`average_price` is a VWAP neither exchange publishes.** Turnover ÷ volume, per security per session, straight from two printed numbers.
- **Valuation is joined on by header, never by position.** TWSE's P/E report changed shape in the mid-2010s and *swapped the P/E and dividend yield columns* while doing it. The 2010 layout is `日期 / 本益比 / 殖利率 / 股價淨值比`; today's is `日期 / 殖利率 / 股利年度 / 本益比 / 股價淨值比 / 財報年季`. Parse by position and every historical P/E you pull is actually a yield. Every table here is read by column name.
- **Two official reports per session, and the Actor reads both.** Each exchange publishes the same session twice — once per security for a whole month, once per day for the whole board. `crossCheck` reads the second copy and compares it column by column. On TWSE the two agree to the last digit. On TPEX they do not, and the Actor says so rather than picking one silently (see below).
- **Nobody serves this in English.** The sources are four Chinese report endpoints per exchange, in Republic-of-China dates, with three different volume units between them and a host that resets the connection if you ask too quickly.

### Output

One record per security per trading session. TSMC on an ordinary day:

```json
{
  "date": "2026-08-14",
  "market": "TWSE",
  "code": "2330",
  "name": "台積電",
  "open": 2435.0,
  "high": 2440.0,
  "low": 2395.0,
  "close": 2395.0,
  "change": -40.0,
  "change_pct": -1.6427,
  "previous_reference_price": 2435.0,
  "previous_close": 2435.0,
  "change_basis": "PREVIOUS_CLOSE",
  "ex_rights_marker": null,
  "volume_shares": 21162682,
  "turnover_value": 51159731253,
  "transactions": 105889,
  "average_price": 2417.450267,
  "last_bid_price": null,
  "last_ask_price": null,
  "issued_shares": null,
  "next_limit_up": null,
  "next_limit_down": null,
  "source_report": "TWSE STOCK_DAY",
  "ohlc_consistent": true,
  "average_price_in_range": true,
  "pe_ratio": 27.76,
  "pb_ratio": 9.66,
  "dividend_yield_pct": 0.92,
  "dividend_per_share": null,
  "dividend_year_roc": 114,
  "fiscal_period": "115/2",
  "dividend_yield_matches_dividend": null
}
```

`last_bid_price`, `last_ask_price`, `issued_shares` and the two limit prices are `null` above because this row came from the per-security report, which does not carry them. Run without `stockCodes` and the whole-board report fills them in.

And an ex-rights session on the OTC board, where the exchange gives you no marker:

```json
{
  "date": "2026-07-23",
  "market": "TPEX",
  "code": "5483",
  "name": "中美晶",
  "close": 212.5,
  "change": -19.0,
  "previous_reference_price": 231.5,
  "previous_close": 234.0,
  "change_basis": "EX_RIGHTS_REFERENCE",
  "ex_rights_marker": "IMPLIED",
  "source_report": "TPEX tradingStock"
}
```

### Input

| Field | What it does |
| --- | --- |
| `stockCodes` | Ticker codes such as `2330`, `0050`, `5483`. Empty means the whole board. |
| `startDate` / `endDate` | `YYYY-MM-DD`. Empty means the latest session. |
| `markets` | `TWSE`, `TPEX`, or both. |
| `includeValuation` | Join P/E, price-to-book and dividend yield. Doubles the request count. |
| `onlyTraded` | Drop securities that did not trade. |
| `crossCheck` | Read one session from the second official report and compare. |
| `fetchStrategy` | `AUTO` (recommended), `BY_STOCK` or `BY_DATE`. |

**Naming stock codes is what makes long histories cheap.** The per-security reports return a whole month per request, so ten years of TSMC is 120 requests; the whole-board reports return one session per request, so ten years of everything is 3,650. `AUTO` picks the right one for you: per-security when you name codes, whole-board when you do not.

Archive floors, each rejected up front rather than returning an empty run:

| | TWSE | TPEX |
| --- | --- | --- |
| Whole board (`BY_DATE`) | 2004-02-11 | 2007-07-02 |
| Per security (`BY_STOCK`) | 2010-01-04 | 2003-04-01 |

Per-run ceilings: 90 calendar days for a whole-board run (a session is ~2,400 records across both markets), 600 report requests for a per-security run.

### Things this dataset is honest about

**TPEX's two reports disagree on volume.** Same exchange, same session, same security, two official endpoints:

| 5483 中美晶, 2026-08-14 | Volume | Turnover |
| --- | --- | --- |
| 個股日成交資訊 (per security) | 25,996,000 shares | NT$4,884,791,000 |
| 每日收盤行情 (whole board) | 25,504,000 shares | NT$4,792,524,000 |

Open, high, low and close are **identical** between the two; only volume and turnover differ, with the per-security figure larger by 0–6%. The gap scales with the share price, which points at intraday odd-lot trading being folded into one report and not the other — but TPEX documents neither report's coverage, and the difference is **not** explained by the after-hours fixed-price feed (`tpex_off_market`), the after-hours odd-lot feed (`tpex_odd_stock`) or the block-trade feed, all of which were checked and are orders of magnitude too small. So the Actor does not pick a winner: `source_report` on every row says which report it came from, and with `crossCheck` on, the run log states the gap in shares. TWSE's two reports have no such problem — they agree to the last digit.

**Turnover ÷ volume sometimes lands outside the day's range.** That is block trading, not a parsing error. Both exchanges fold block trades into the daily totals, and a block prices against the previous close rather than the day's band. 元大金 2885 on 2026-08-25 traded 16,043,105 shares for NT$1,009,573,854, an average of 62.928832 against a 62.00–62.80 range. Take out the single 1,400,000-share pair trade at 68.60 that the official block-trade report lists for that session and the average falls to 62.386622 — back inside the band. `average_price_in_range` flags these so you can find them, not because they are wrong.

**TPEX's published yield did not always follow from the dividend it publishes beside it.** Both numbers are given as-is and `dividend_yield_matches_dividend` says whether they reconcile. One session a year: 24/361 rows reconcile in 2011 and 40/381 in 2013, against 380/469 in 2015, 436/514 in 2020 and 596/603 in 2026. Treat pre-2015 TPEX yields with care.

**P/E is absent more often than it is present, and that is correct.** The exchanges print a dash for a loss-making company and a zero for every ETF; both become `null` here rather than a misleading `0.0`. On 2026-08-14 the TWSE quote report carried 1,378 securities, the valuation report covered 1,083 of them, and 869 of those had a P/E.

**A security sits on exactly one board.** Asking for `2330` with both markets selected costs one wasted request against TPEX, which answers "no data". Narrow `markets` if you know where your codes live.

### Taiwan Market Data Suite

This Actor is part of a suite of 25 Taiwan market data APIs by [chamarix](https://apify.com/chamarix) — official sources only, cross-validated against independent official endpoints, clean JSON out. Code samples for the whole suite: [GitHub](https://github.com/cc77556/taiwan-market-data-actors).

**Market data:**

- [twse-institutional-trades](https://apify.com/chamarix/twse-institutional-trades) — Daily institutional buy/sell (foreign, investment trust, dealer) per stock — TWSE listed
- [tpex-institutional-trades](https://apify.com/chamarix/tpex-institutional-trades) — Daily institutional buy/sell per stock — TPEx OTC market
- [taiwan-monthly-revenue](https://apify.com/chamarix/taiwan-monthly-revenue) — Monthly revenue of 1,900+ listed & OTC companies, MoM/YoY
- [taiwan-financial-statements](https://apify.com/chamarix/taiwan-financial-statements) — Quarterly income statement, balance sheet & cash flow back to 2013
- [taiwan-dividend-calendar](https://apify.com/chamarix/taiwan-dividend-calendar) — Ex-dividend / ex-rights dates, reference prices & payouts back to 2003
- [taiwan-margin-trading](https://apify.com/chamarix/taiwan-margin-trading) — Daily margin trading & short sale balances per stock
- [taiwan-sbl-short-sale-balance](https://apify.com/chamarix/taiwan-sbl-short-sale-balance) — Securities-lending short sale balances per stock
- [taiwan-day-trading-stats](https://apify.com/chamarix/taiwan-day-trading-stats) — Day-trading volume, value & ratio per stock since 2014
- [tdcc-shareholding-dispersion](https://apify.com/chamarix/tdcc-shareholding-dispersion) — Weekly TDCC shareholding dispersion (retail vs whale structure)
- [taiwan-foreign-shareholding](https://apify.com/chamarix/taiwan-foreign-shareholding) — Foreign ownership percentage & remaining quota per stock
- [taifex-institutional-derivatives](https://apify.com/chamarix/taifex-institutional-derivatives) — Institutional futures & options positions (TAIFEX), incl. put/call ratio
- [taifex-options-chain](https://apify.com/chamarix/taifex-options-chain) — Full options chain by strike & expiry, both sessions, with the exchange's own Delta, since 2001
- [taiwan-warrants-daily](https://apify.com/chamarix/taiwan-warrants-daily) — Daily quotes, strike, expiry & moneyness for every listed/OTC warrant since 2004
- [taiwan-stock-alerts](https://apify.com/chamarix/taiwan-stock-alerts) — Watch-list, disposition & short-sale suspension alerts
- [taiwan-insider-share-transfers](https://apify.com/chamarix/taiwan-insider-share-transfers) — Insider share-transfer filings (directors, officers, 10% holders) since 2002
- [taiwan-director-shareholdings](https://apify.com/chamarix/taiwan-director-shareholdings) — Monthly director/officer shareholdings & share-pledge ratio since 1999
- [taiwan-block-trades](https://apify.com/chamarix/taiwan-block-trades) — Every block trade (鉅額交易) with price, size & basket constituents since 2005
- [taiwan-shareholder-meetings](https://apify.com/chamarix/taiwan-shareholder-meetings) — Shareholder meeting dates, book closure periods & e-voting since 2005
- [taiwan-emerging-stock-quotes](https://apify.com/chamarix/taiwan-emerging-stock-quotes) — Emerging (興櫃) board quotes, pre-IPO register & history since 2003
- [taiwan-etf-regular-investment](https://apify.com/chamarix/taiwan-etf-regular-investment) — Monthly regular savings plan (定期定額) rankings for stocks & ETFs since 2020
- [taiwan-treasury-stock-buybacks](https://apify.com/chamarix/taiwan-treasury-stock-buybacks) — Every treasury-stock buyback (庫藏股) filing, plan vs execution, since 2000

**Property market:**

- [taiwan-real-estate-transactions](https://apify.com/chamarix/taiwan-real-estate-transactions) — Actual registered sale, presale & lease prices (實價登錄) for all 22 cities since 2012

**Government & civic data:**

- [taiwan-legislator-monitor](https://apify.com/chamarix/taiwan-legislator-monitor) — Legislative Yuan bills, legislators & meetings
- [taiwan-tender-monitor](https://apify.com/chamarix/taiwan-tender-monitor) — Government e-procurement tenders (open calls, awards, failures)

### Data source

Taiwan Stock Exchange 個股日成交資訊 (STOCK\_DAY), 每日收盤行情 (MI\_INDEX), 個股日本益比、殖利率及股價淨值比 (BWIBBU, BWIBBU\_d); Taipei Exchange 個股日成交資訊 (tradingStock), 上櫃股票每日收盤行情 (otc), 本益比、殖利率及股價淨值比 (peQryStock, peQryDate), and the 上櫃股票每日收盤行情 open-data mirror used for independent verification. Public data, no login required.

# Actor input Schema

## `markets` (type: `array`):

TWSE is the main board (~1,380 securities a session, including ETFs and TDRs); TPEX is the over-the-counter board (~1,010). A security sits on exactly one of them, so naming both costs one wasted request per code that is not on the other board.

## `stockCodes` (type: `array`):

Ticker codes such as 2330, 0050 or 5483. Leave empty for every security on the board. Naming codes also switches the Actor to the per-security reports, which return a whole month per request — that is the cheap way to pull years of history for a handful of names.

## `startDate` (type: `string`):

First trading day to fetch. Leave both dates empty for the latest session. Archive floors, each rejected up front rather than silently returning nothing: whole-board TWSE 2004-02-11, whole-board TPEX 2007-07-02, per-security TWSE 2010-01-04, per-security TPEX 2003-04-01.

## `endDate` (type: `string`):

Last trading day to fetch, inclusive. A whole-board session is about 2,400 records across both markets, so 90 calendar days is the ceiling for a whole-board run. Non-trading days cost one request and are skipped.

## `includeValuation` (type: `boolean`):

Joins the exchanges' valuation reports onto the quotes. It doubles the request count, so turn it off for a pure price-and-volume pull. TWSE publishes valuation from 2005-09-02 onward; earlier sessions come back with the ratios empty.

## `onlyTraded` (type: `boolean`):

Drops rows with zero volume. Both boards list securities that go whole sessions without a trade; the exchange still prints a row for them, with dashes where the prices would be.

## `crossCheck` (type: `boolean`):

Each exchange publishes every session twice — once per security, once per day for the whole board. With this on, one session is read from the other report and compared column by column, and the result is written to the log. Costs one or two extra requests per run.

## `fetchStrategy` (type: `string`):

AUTO picks per-security when stock codes are named and whole-board otherwise, which is the cheaper choice in almost every case. Override it only to compare the two reports yourself — they do not agree on TPEX volume.

## Actor input object example

```json
{
  "markets": [
    "TWSE",
    "TPEX"
  ],
  "stockCodes": [],
  "startDate": "",
  "endDate": "",
  "includeValuation": true,
  "onlyTraded": false,
  "crossCheck": true,
  "fetchStrategy": "AUTO"
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

One record per security per trading session — open, high, low, close, change, volume, turnover and trade count, with P/E, price-to-book and dividend yield joined on and the exchange's ex-rights marker resolved.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "markets": [
        "TWSE",
        "TPEX"
    ],
    "stockCodes": [],
    "startDate": "",
    "endDate": "",
    "includeValuation": true,
    "onlyTraded": false,
    "crossCheck": true,
    "fetchStrategy": "AUTO"
};

// Run the Actor and wait for it to finish
const run = await client.actor("chamarix/taiwan-stock-daily-quotes").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "markets": [
        "TWSE",
        "TPEX",
    ],
    "stockCodes": [],
    "startDate": "",
    "endDate": "",
    "includeValuation": True,
    "onlyTraded": False,
    "crossCheck": True,
    "fetchStrategy": "AUTO",
}

# Run the Actor and wait for it to finish
run = client.actor("chamarix/taiwan-stock-daily-quotes").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "markets": [
    "TWSE",
    "TPEX"
  ],
  "stockCodes": [],
  "startDate": "",
  "endDate": "",
  "includeValuation": true,
  "onlyTraded": false,
  "crossCheck": true,
  "fetchStrategy": "AUTO"
}' |
apify call chamarix/taiwan-stock-daily-quotes --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chamarix/taiwan-stock-daily-quotes"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/egcPCkQxkAsBuegmF/builds/ygT3N2ko92qtvJIw1/openapi.json
