# Taiwan Quarterly Financial Statements (TWSE + TPEx) (`chamarix/taiwan-financial-statements`) Actor

Income statement, balance sheet and cash flow for every Taiwan listed, OTC, emerging and public-issue company, straight from MOPS. Full quarterly history back to 2013Q1, every published line item plus normalized metrics, with the accounting identities checked on every row.

- **URL**: https://apify.com/chamarix/taiwan-financial-statements.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/platform/actors/running/actors-in-store#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 Quarterly Financial Statements (TWSE + TPEx)

Get structured JSON access to the **income statement, balance sheet and cash flow statement of every company that files with Taiwan's Market Observation Post System** — listed, OTC, emerging board and unlisted public-issue — with full quarterly history back to **2013Q1**.

Taiwan publishes price, volume and institutional flow data generously. Fundamentals are the gap: the exchanges' open-data feeds carry only the single most recent quarter, and it is scattered across a dozen endpoints with a different column set per industry. This Actor reads the MOPS 彙總報表 tables that hold the entire history, normalizes the six industry layouts into one schema, and checks the accounting identities on every row it emits.

### Why this data matters

- **Complete history, not the latest snapshot.** Every quarter from 2013Q1 — the quarter Taiwan adopted IFRS — through the current filing season. 13 years of comparable statements for backtests, screens and valuation models.
- **All three statements, joined.** One record per company per quarter carries all three. No key-matching across separate feeds, no reconciling a balance sheet against an income statement filed under a different schema.
- **Every published line item, not a summary.** Alongside 30 normalized metrics you get `line_items` — the complete official caption-to-value map, 59 captions deep on a bank's balance sheet. Nothing the exchange publishes is dropped.
- **Six industry layouts, one schema.** A bank reports 利息淨收益 where a manufacturer reports 營業收入; an insurer's balance sheet has no 流動資產 at all. Banks, securities firms, financial holding companies, insurers, general industries and other financial businesses are all normalized to the same field names, with `industry_layout` telling you which one you are looking at.
- **The unlisted universe too.** `market: "all"` adds the emerging stock board (pre-IPO companies) and public-issue filers — including subsidiaries like 臺灣金控 and foreign bank branches that have no ticker anywhere.

### Output

One record per company per fiscal quarter. **All money figures are in NT$ thousands (新台幣仟元)**; `eps` and `book_value_per_share` are in NT$, and any caption ending 單位：股 is a share count.

```json
{
  "period": "2025Q4",
  "fiscal_year": 2025,
  "fiscal_quarter": 4,
  "roc_year": 114,
  "market": "TWSE",
  "company_code": "2330",
  "company_name": "台積電",
  "industry_layout": "general",
  "income_tax_printed_as": "expense_positive",
  "income_statement": {
    "revenue": 3809054272,
    "cost_of_revenue": 1527760293,
    "gross_profit": 2281293979,
    "operating_expenses": 345649630,
    "operating_income": 1936091677,
    "pretax_income": 2041662840,
    "income_tax_expense": 326266060,
    "net_income": 1715396780,
    "net_income_parent": 1717882627,
    "comprehensive_income": 1659070261,
    "eps": 66.26
  },
  "balance_sheet": {
    "current_assets": 3817130817,
    "total_assets": 7933023878,
    "current_liabilities": 1458019289,
    "total_liabilities": 2472228595,
    "share_capital": 259325245,
    "capital_surplus": 73445601,
    "retained_earnings": 5103501560,
    "treasury_stock": 0,
    "equity_parent": 5419595994,
    "non_controlling_interests": 41199289,
    "total_equity": 5460795283,
    "book_value_per_share": 208.99
  },
  "cash_flow": {
    "operating_cash_flow": 2274975625,
    "investing_cash_flow": -1144393407,
    "financing_cash_flow": -440344692,
    "fx_effect_on_cash": -50008167,
    "net_change_in_cash": 640229359,
    "cash_at_beginning": 2127627043,
    "cash_at_end": 2767856402
  },
  "line_items": { "income_statement": { "營業收入": 3809054272, "...": "..." } },
  "identity_ok": true,
  "identity_checks_run": 5,
  "identity_checks_passed": 5,
  "identity_failures": []
}
```

| Field | Meaning |
|---|---|
| `period` / `fiscal_year` / `fiscal_quarter` | Fiscal quarter, as `2025Q4` and as parts |
| `roc_year` | The ROC year MOPS files it under (Gregorian − 1911) |
| `market` | `TWSE`, `TPEX`, `EMERGING` or `PUBLIC` |
| `company_code` / `company_name` | As filed. For listed, OTC and emerging companies the code is the ticker |
| `industry_layout` | `general`, `banking`, `securities`, `financial_holding`, `insurance` or `other` |
| `income_tax_printed_as` | `expense_positive`, or `income_negative` for the financial tables up to 2017Q4 |
| `income_statement` | 11 normalized metrics from 綜合損益表 |
| `balance_sheet` | 12 normalized metrics from 資產負債表 |
| `cash_flow` | 7 normalized metrics from 現金流量表 |
| `line_items` | Every official caption and value, per statement. Switch off with `includeAllLineItems` |
| `identity_ok` and friends | Which accounting identities were checked, and whether they held |

A normalized metric is `null` when this company's layout does not publish it — a bank has no `gross_profit`, an insurer has no `current_assets`. A whole statement is `null` when it was not requested, or when the company had not filed it for that quarter.

#### Four things about Taiwanese quarterly filings that will bite you

**1. Quarters are year-to-date cumulative, not discrete.** The exchange states it on the report: 本表各季別資料係揭露該年度截至該季止之累計金額. `2025Q4` revenue is the full 2025 financial year; `2025Q2` is the first half. To get a discrete quarter, difference consecutive periods — Q3 minus Q2 — and take Q1 as-is. Balance-sheet figures are point-in-time and need no differencing; cash-flow figures are cumulative like the income statement.

**2. A quarter fills in over six weeks, by industry.** Filing deadlines differ: general industries file Q2 by 14 August, while banks, insurers, securities firms and financial holding companies have until 31 August. Requesting the current quarter mid-season returns whoever has filed so far — on 12 August 2026, TWSE 2026Q2 had 446 companies rather than the eventual ~1,050. Re-run a quarter after its last deadline for a complete set.

**3. There is no single "revenue" line across industries.** `revenue` maps to 營業收入 for a manufacturer, 收益 for a securities firm, 淨收益 for a financial holding company and 收入 for other financial businesses — and stays `null` for banks, which report 利息淨收益 and 利息以外淨損益 with no combined top line. Check `industry_layout` before comparing a ratio across sectors, or read the exact captions out of `line_items`.

**4. Income tax changed sign in 2018, and the caption did not.** Through 2017Q4, the bank, securities-firm and financial-holding tables printed income tax as a *negative income item* — 彰銀 2016Q3 shows `-1,610,719`, and you add it to pre-tax profit to get profit after tax. From 2018Q1 they print a positive expense you subtract. The heading never moved with it: financial holding companies still say 所得稅（費用）利益 today while printing a positive number, so you cannot read the convention off the caption. This Actor reads it off the table — every row that publishes pre-tax profit, tax and continuing-operations profit has to agree on one convention or the run fails — and normalizes `income_tax_expense` so a positive figure always means tax paid. `income_tax_printed_as` records what the source did, and `line_items` keeps the figure exactly as printed.

### Data integrity

Financial statements are the one dataset where a mis-mapped column is invisible until it corrupts a model, so the parse is verified three ways.

**Accounting identities, on every row of every run.** Five identities are asserted per company, and only when every input was actually published:

- `total_assets = total_liabilities + total_equity`
- `total_equity = equity_parent + non_controlling_interests`
- `pretax_income − income_tax_expense = continuing-operations profit`
- `operating + investing + financing + fx = net_change_in_cash`
- `cash_at_beginning + net_change_in_cash = cash_at_end`

Across TWSE 2025Q4 (1,084 companies), TPEx 2025Q4 (890) and TWSE 2013Q1 (784) that is **12,774 identity checks with zero failures**. Results ride along on each record in `identity_ok` and `identity_failures`, so a future filing error is visible in the data rather than silent.

**Every value cross-checked against the open-data mirror.** The TWSE and TPEx publish the current quarter independently through their open-data APIs (`t187ap06_L_ci`, `t187ap07_L_ci` and the TPEx `mopsfin_*` equivalents), produced by a different pipeline from the MOPS tables this Actor reads. Comparing the two, caption by caption, for 2026Q2: **34,398 values, zero differences**, with no company present in the mirror missing from the output.

**Historical quarters checked against the filers' own statements.** The open-data mirrors only carry the newest quarter, so history is verified against MOPS' per-company reports, rendered from each company's own XBRL submission through an entirely separate query path. Sampling 台積電 2025Q4, 鴻海 2025Q4, 國泰金 2020Q2 and 彰銀 2016Q3 — spanning the general, financial-holding and banking layouts and both sides of the 2018 tax-sign change — all 28 sampled figures matched.

Beyond that, the parser refuses to guess. Industry tables are matched by header signature rather than position, because MOPS omits an industry's table entirely when nobody in it has filed yet and the table order shifts during filing season. An unrecognized layout, a row whose cell count does not match its header, or an income-tax column whose rows disagree about the sign convention all fail the run loudly instead of emitting mis-aligned numbers.

### Input

| Field | Type | Description |
|---|---|---|
| `startPeriod` | string (required) | `YYYYQn`, e.g. `2025Q4`. History starts at `2013Q1` |
| `endPeriod` | string | `YYYYQn` inclusive; empty = just the start period |
| `market` | string | `both` (default, TWSE + TPEx), `twse`, `tpex`, `emerging`, `public`, or `all` |
| `statements` | array | Any of `income_statement`, `balance_sheet`, `cash_flow`. Default all three |
| `stockCodes` | array | Optional filter, e.g. `["2330", "2317"]`. Empty = every company |
| `includeAllLineItems` | boolean | Attach the full official caption map. Default `true` |

Example — the full 2025 financial year for the listed and OTC markets:

```json
{
  "startPeriod": "2025Q4",
  "market": "both"
}
```

Example — ten years of quarterly fundamentals for three semiconductor names:

```json
{
  "startPeriod": "2016Q1",
  "endPeriod": "2025Q4",
  "market": "both",
  "stockCodes": ["2330", "2454", "3711"]
}
```

Example — a compact cash-flow-only screen across everything that files:

```json
{
  "startPeriod": "2025Q4",
  "market": "all",
  "statements": ["cash_flow"],
  "includeAllLineItems": false
}
```

### Pricing & cost control

Pay per result: **$0.50 / 1,000 records**.

- Full listed + OTC market, one quarter: 1,974 records ≈ $0.99 (measured on 2025Q4)
- Ten years of quarterly history for 3 tickers: 120 records ≈ $0.06
- One company, every quarter since 2013: 52 records ≈ $0.03

Cost scales with companies × quarters, and not at all with how many statements you request — all three arrive in the same record. A full-market quarter ran 1,084 TWSE plus 890 TPEx companies in 2025Q4 and 784 TWSE companies in 2013Q1, so a long full-market backfill runs to tens of thousands of records; filter by `stockCodes` for time-series work and take one quarter at a time for cross-sectional screens.

### Data source & reliability

- Direct from MOPS 彙總報表 綜合損益表 / 資產負債表 / 現金流量表 (`t163sb04`, `t163sb05`, `t163sb20`) — the exchange's own tables, no third-party intermediaries
- Coverage starts at 2013Q1 because that is when Taiwan adopted IFRS; ROC 101 and earlier return nothing for every market, and the Actor rejects those periods up front rather than emitting empty runs
- A quarter that has not been published yet is reported as such in the log and produces no rows — it is not an error
- Statement captions have changed over 13 years (呆帳費用及保證責任準備提存 became 呆帳費用、承諾及保證責任準備提存 in the bank layout; 權益─具證券性質之虛擬通貨 was added). Values are read by caption, so both old and new pages parse and a future rename surfaces as a failed run rather than a shifted column
- Reports refresh as companies file; run after the last deadline of a quarter (31 August for Q2, 14 November for Q3, 31 March for the annual report) for a settled set

### Use cases

- Fundamental screeners — margin, leverage, cash conversion and ROE across the whole Taiwan market
- Backtesting factor models on 13 years of point-in-time quarterly fundamentals
- Valuation models needing revenue, earnings and book value per share on a consistent schema
- Credit and counterparty analysis of banks, insurers and financial holding companies, whose statements no generic feed handles
- Pre-IPO research on the emerging stock board, where fundamentals are otherwise unavailable in English
- Cash-flow quality checks — comparing operating cash flow against reported earnings to flag accrual-heavy quarters

### Related Actors

- [Taiwan Monthly Revenue](https://apify.com/chamarix/taiwan-monthly-revenue) — the monthly top-line filings between quarterly statements
- [Taiwan Dividend Calendar](https://apify.com/chamarix/taiwan-dividend-calendar) — what these earnings get paid out as
- [Taiwan Foreign & Mainland Shareholding](https://apify.com/chamarix/taiwan-foreign-shareholding) — who owns the companies
- [Taiwan Insider Share Transfers](https://apify.com/chamarix/taiwan-insider-share-transfers) — what management is doing with its own stock
- [Taiwan Shareholding Dispersion (TDCC)](https://apify.com/chamarix/tdcc-shareholding-dispersion) — weekly retail vs whale ownership
- [TWSE Institutional Trades](https://apify.com/chamarix/twse-institutional-trades) — daily foreign, trust and dealer flow

***

### Taiwan Market Data Suite

This Actor is part of a suite of 19 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-dividend-calendar](https://apify.com/chamarix/taiwan-dividend-calendar) — Ex-dividend / ex-rights dates, reference prices & payouts back to 2003
- [taiwan-shareholder-meetings](https://apify.com/chamarix/taiwan-shareholder-meetings) — Shareholder meeting dates, book closure periods, board elections & e-voting since 2005
- [taiwan-emerging-stock-quotes](https://apify.com/chamarix/taiwan-emerging-stock-quotes) — Emerging Stock Board (興櫃) quotes, pre-IPO company register & listing-application status
- [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
- [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

**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)

# Actor input Schema

## `startPeriod` (type: `string`):

First fiscal quarter to fetch, as YYYYQn (e.g. 2025Q1). History starts at 2013Q1, the quarter Taiwan adopted IFRS. Figures are year-to-date cumulative, so Q4 is the full financial year.

## `endPeriod` (type: `string`):

Last fiscal quarter to fetch, inclusive. Leave empty to fetch only the start period.

## `market` (type: `string`):

Which MOPS filing population to fetch.

## `statements` (type: `array`):

Which of the three statements to fetch. Each one is a separate request per market-quarter, so dropping the ones you do not need makes the run faster.

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

Optional list of company codes to keep (e.g. \['2330', '2317']). Leave empty for every company in the selected markets.

## `includeAllLineItems` (type: `boolean`):

Attach the complete official caption-to-value map for each statement under line\_items, on top of the normalized metrics. Turn this off for a compact dataset with only the normalized fields.

## Actor input object example

```json
{
  "startPeriod": "2025Q4",
  "endPeriod": "",
  "market": "both",
  "statements": [
    "income_statement",
    "balance_sheet",
    "cash_flow"
  ],
  "stockCodes": [
    "2330",
    "2317",
    "2454"
  ],
  "includeAllLineItems": true
}
```

# 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 = {
    "startPeriod": "2025Q4",
    "market": "both",
    "statements": [
        "income_statement",
        "balance_sheet",
        "cash_flow"
    ],
    "stockCodes": [
        "2330",
        "2317",
        "2454"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chamarix/taiwan-financial-statements").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 = {
    "startPeriod": "2025Q4",
    "market": "both",
    "statements": [
        "income_statement",
        "balance_sheet",
        "cash_flow",
    ],
    "stockCodes": [
        "2330",
        "2317",
        "2454",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("chamarix/taiwan-financial-statements").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 '{
  "startPeriod": "2025Q4",
  "market": "both",
  "statements": [
    "income_statement",
    "balance_sheet",
    "cash_flow"
  ],
  "stockCodes": [
    "2330",
    "2317",
    "2454"
  ]
}' |
apify call chamarix/taiwan-financial-statements --silent --output-dataset

```

## MCP server setup

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

```

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/3JoPyX18MD55XVj6J/builds/LM0RqxDLlva63HcXs/openapi.json
