# Taiwan Foreign & Mainland Shareholding (TWSE + TPEx) (`chamarix/taiwan-foreign-shareholding`) Actor

Daily foreign and mainland-Chinese ownership for all 2,200+ Taiwan listed & OTC securities: issued shares, shares held, shares still available, statutory ownership caps and quota utilisation in one normalized JSON schema. Official TWSE/TPEx data back to 2004.

- **URL**: https://apify.com/chamarix/taiwan-foreign-shareholding.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 Foreign & Mainland Shareholding (TWSE + TPEx)

Get structured JSON access to **daily foreign ownership for every Taiwan-listed and OTC security** — how many shares overseas and mainland-Chinese investors hold, how many they may still buy, and how close they are to the legal ceiling.

Institutional trade data tells you the **flow** — who bought and sold today. This Actor gives you the **stock**: the accumulated position, per security, per day, straight from the exchanges' own 外資及陸資投資持股統計 and 僑外資及陸資持股比例排行表 reports.

### Why this data matters

- **Foreign ownership is the single most-watched positioning metric in Taiwan equities.** TSMC sits around 69% foreign-held; a multi-point drift in that number is a macro event, not a stock story.
- **Quota squeezes are real and tradeable.** Telecoms, broadcasting, aviation, shipping and defence names carry statutory ceilings — 49%, 49.99%, 19%, even 0%. When foreign investors approach the cap, buying pressure has nowhere to go and the shares trade at a premium. `quota_utilization_pct` measures exactly that, and `capRestrictedOnly` narrows the run to the ~29 securities where it can happen.
- **Ownership stock vs. institutional flow.** Cross-referenced with daily buy/sell data, the change in held shares separates genuine accumulation from intraday churn.
- **Non-trading changes are flagged.** The TWSE marks rows whose holdings moved because of a capital increase, a GDR conversion or a corrected filing rather than market trading — so you can exclude them before computing a flow.
- **20+ years of history.** TWSE back to 2004-02-11, TPEx back to 2007-05-02, at daily granularity, with the pre-2009 layout (before mainland investors were admitted at all) parsed correctly.

### Output

One record per security per trading day, 21 normalized fields. **All share counts are in shares (股), not lots.**

```json
{
  "date": "2026-08-07",
  "market": "TWSE",
  "stock_code": "2330",
  "stock_name": "台積電",
  "isin": "TW0002330008",
  "issued_shares": 25932370067,
  "foreign_held_shares": 17931083542,
  "foreign_available_shares": 8001286525,
  "foreign_held_pct": 69.14,
  "foreign_available_pct": 30.85,
  "foreign_ownership_cap_pct": 100.0,
  "mainland_ownership_cap_pct": 100.0,
  "quota_utilization_pct": 69.1456,
  "reserved_shares": 0,
  "available_shares_matches_formula": true,
  "rank": null,
  "change_reason_code": null,
  "change_reason": "Ordinary secondary-market trading by foreign/mainland investors",
  "last_reported_change_date": "2026-05-26",
  "note": null,
  "held_pct_recomputed": 69.145564
}
```

| Field | Meaning |
|---|---|
| `issued_shares` | 發行股數 — shares issued, as filed with the exchange |
| `foreign_held_shares` | 全體外資及陸資持有股數 — shares held by all foreign + mainland investors |
| `foreign_available_shares` | 尚可投資股數 — shares they may still buy before the cap binds |
| `foreign_held_pct` / `foreign_available_pct` | The two official percentages, as printed |
| `foreign_ownership_cap_pct` | 法令投資上限比率 — statutory ceiling on combined foreign + mainland ownership |
| `mainland_ownership_cap_pct` | 陸資法令投資上限比率 — separate ceiling for mainland investors alone (TWSE, 2009+) |
| `quota_utilization_pct` | `held / (issued × cap)` — how much of the legal quota is used |
| `reserved_shares` | Shares withheld from availability for approved-but-unissued GDRs and similar |
| `available_shares_matches_formula` | `false` on the ~0.6% of rows carrying reserved shares |
| `rank` | TPEx publishes its table ranked by holding percentage; TWSE does not (null) |
| `change_reason_code` / `change_reason` | TWSE footnote 2–5, explaining a non-trading change vs. the previous session |
| `last_reported_change_date` | When the company last filed a holdings change (TWSE) |
| `held_pct_recomputed` | Holding percentage at 6 decimals, for screens where 2dp is too coarse |

#### The metric that isn't obvious

For the ~98% of securities with a 100% cap, `quota_utilization_pct` is just the holding percentage. For the rest it is a different number entirely — and it is the one that matters:

| Security | Foreign held | Statutory cap | Quota used |
|---|---|---|---|
| 中華電 2412 Chunghwa Telecom | 17.28% | 49% | **35.28%** |
| 長榮 2603 Evergreen Marine | 21.78% | 49.99% | **43.59%** |
| 萬海 2615 Wan Hai Lines | 44.78% | 49.99% | **89.59%** |
| 新興 2605 Sincere Navigation | 49.75% | 49.99% | **99.54%** |

Sincere Navigation has 0.23% of its shares left before foreign investors are legally shut out. A screener sorting on raw holding percentage would never surface it above TSMC.

#### Data integrity

The exchanges print both percentages alongside the share counts they derive from, which makes the parse self-checking. On every run, for every row:

- `foreign_held_pct` must equal `held / issued`, floored to 2 decimals — matched **1,358/1,358** TWSE and **891/891** TPEx rows on 2026-08-07
- `foreign_available_pct` must equal `available / issued` — TWSE floors it, TPEx rounds it; both matched 100% of rows

Left on by default, `verifyWithIndustryTotals` adds a second, independent check: the TWSE publishes a separate industry-level aggregate (`MI_QFIIS_cat`), and the Actor asserts that its own row set reconciles with it exactly — security count, issued shares and held shares all to the share. On 2026-08-07 that was 1,358 securities, 1,055,188,705,522 issued shares and 176,571,051,231 held, with zero difference.

Issued-share counts were separately cross-checked against the MOPS company filings feed (`t187ap03_L`): 1,018 of 1,093 matched exactly, with the remainder explained by ordinary reporting lag between the daily exchange report and the monthly company filing.

### Input

| Field | Type | Description |
|---|---|---|
| `startDate` | string (required) | `YYYY-MM-DD`. TWSE from 2004-02-11, TPEx from 2007-05-02 |
| `endDate` | string | `YYYY-MM-DD` inclusive; empty = single day |
| `market` | string | `both` (default), `twse`, or `tpex` |
| `stockCodes` | array | Optional filter, e.g. `["2330", "5274"]`. Empty = all (~2,250 securities/day) |
| `minForeignHoldingPct` | integer | Only return securities held at least this much by foreign investors. `0` = no filter |
| `capRestrictedOnly` | boolean | Only securities whose statutory cap is under 100% — the quota-squeeze universe |
| `verifyWithIndustryTotals` | boolean | Cross-check the latest session against the TWSE industry aggregate. Default `true` |

Example — one month of foreign ownership for three tickers:

```json
{
  "startDate": "2026-07-08",
  "endDate": "2026-08-07",
  "market": "both",
  "stockCodes": ["2330", "2317", "5274"]
}
```

Example — the quota-squeeze universe, one day:

```json
{
  "startDate": "2026-08-07",
  "market": "both",
  "capRestrictedOnly": true
}
```

### Pricing & cost control

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

- Full market (TWSE + TPEx), one day: ~2,250 records ≈ $1.12
- Filtered to 5 tickers, one month: ~110 records ≈ $0.06
- `capRestrictedOnly: true`, one day: ~29 records ≈ $0.02

For time-series work, filter by `stockCodes` — a year of daily history for a handful of tickers costs cents, while a year of the full market is 550,000+ records.

### Data source & reliability

- Direct from the official TWSE `MI_QFIIS` and TPEx 僑外資及陸資持股比例排行表 feeds — no third-party intermediaries
- The TWSE renamed every column in 2009 when mainland investment was admitted (外資 → 外資及陸資, plus a new mainland-only cap). Columns are resolved by header name, so both layouts parse correctly and a future rename fails the run loudly instead of returning silently mis-mapped numbers
- TPEx echoes its latest published session for an out-of-range date; the Actor checks the echoed date and emits nothing rather than mislabelling it
- Weekends are skipped automatically; market holidays return no rows
- The exchanges refresh this report at 18:00 and 22:00 Taipei time; run after 22:00 for settled figures

### Use cases

- Foreign ownership time series for any Taiwan ticker, for factor models and event studies
- Quota-squeeze screeners across regulated sectors — telecoms, aviation, shipping, broadcasting, defence
- Separating genuine foreign accumulation from GDR conversions and capital-increase artefacts
- Index and ETF research where foreign-availability caps affect investability weights
- Compliance and mandate monitoring against statutory foreign ownership ceilings

### Related Actors

- [TWSE Institutional Trades](https://apify.com/chamarix/twse-institutional-trades) — the daily foreign/trust/dealer *flow* behind these ownership changes
- [TPEx Institutional Trades](https://apify.com/chamarix/tpex-institutional-trades) — same for the OTC market
- [Taiwan Short Sale & Securities Lending Balance](https://apify.com/chamarix/taiwan-sbl-short-sale-balance) — foreign institutional bear positioning
- [Taiwan Shareholding Dispersion (TDCC)](https://apify.com/chamarix/tdcc-shareholding-dispersion) — weekly retail vs whale ownership
- [Taiwan Margin Trading](https://apify.com/chamarix/taiwan-margin-trading) — retail leverage on the same securities
- [Taiwan Dividend Calendar](https://apify.com/chamarix/taiwan-dividend-calendar) — ex-dividend dates and payouts

***

### 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-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-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)
- [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

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

Start date in YYYY-MM-DD format. TWSE history goes back to 2004-02-11, TPEx to 2007-05-02.

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

End date in YYYY-MM-DD format (inclusive). Leave empty to scrape only the start date.

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

Which market to fetch: both (TWSE listed + TPEx OTC), twse only, or tpex only.

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

Optional list of stock codes to filter (e.g., \['2330', '5274']). Leave empty to get all securities.

## `minForeignHoldingPct` (type: `integer`):

Only output securities whose foreign + mainland holding percentage is at least this value. Useful for isolating the heavily foreign-owned end of the market. 0 = no filter.

## `capRestrictedOnly` (type: `boolean`):

Restrict output to securities whose legal foreign ownership ceiling is under 100% (telecoms, broadcasting, transport and other regulated sectors). These are the only stocks where a foreign ownership quota squeeze can actually happen — sort them by quota\_utilization\_pct to find the tightest.

## `verifyWithIndustryTotals` (type: `boolean`):

When the run covers the latest TWSE session and no stock filter is set, fetch the independent MI\_QFIIS\_cat industry summary and assert that security count, issued shares and held shares reconcile exactly. Adds one request and logs the result.

## Actor input object example

```json
{
  "startDate": "2026-08-07",
  "endDate": "",
  "market": "both",
  "stockCodes": [
    "2330",
    "2317",
    "5274"
  ],
  "minForeignHoldingPct": 0,
  "capRestrictedOnly": false,
  "verifyWithIndustryTotals": 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 = {
    "startDate": "2026-08-07",
    "market": "both",
    "stockCodes": [
        "2330",
        "2317",
        "5274"
    ],
    "minForeignHoldingPct": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("chamarix/taiwan-foreign-shareholding").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 = {
    "startDate": "2026-08-07",
    "market": "both",
    "stockCodes": [
        "2330",
        "2317",
        "5274",
    ],
    "minForeignHoldingPct": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("chamarix/taiwan-foreign-shareholding").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 '{
  "startDate": "2026-08-07",
  "market": "both",
  "stockCodes": [
    "2330",
    "2317",
    "5274"
  ],
  "minForeignHoldingPct": 0
}' |
apify call chamarix/taiwan-foreign-shareholding --silent --output-dataset

```

## MCP server setup

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

```

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/D1Xet3oibQiI9sRZc/builds/qZok2pv2LBwHNAoth/openapi.json
