ETF Holdings
Retrieve the daily constituent list of a given ETF within a date range, including constituent symbol, name, holding quantity, weight, and change from the previous available data date.
GET /ownership/etf-holdings/{symbol}
Version Note
Available since v2.2.9
Parameters
| Name | Type | Description |
|---|---|---|
symbol* | string | ETF symbol (e.g. 0050, 00981A), path parameter |
from | string | Start date (format: yyyy-MM-dd), defaults to 30 days ago |
to | string | End date (format: yyyy-MM-dd), defaults to today |
sort | string | Sort by date, defaults to desc; asc is also supported |
Response
| Name | Type | Description |
|---|---|---|
symbol* | string | ETF symbol |
type* | string | Security type |
exchange* | string | Exchange |
market* | string | Market |
data* | object[] | Daily constituent data, one entry per date |
data.date* | string | Date |
data.components* | object[] | Constituent list |
data.components.symbol* | string | Constituent symbol (overseas ETFs may return a foreign symbol, e.g. AAPL UQ) |
data.components.name | string | Constituent name |
data.components.quantity | number | Holding quantity (shares) |
data.components.weight | number | Weight (%) |
data.components.quantityChange | number | Change in holding quantity from the previous available data date (omitted on the first available date) |
data.components.weightChange | number | Change in weight from the previous available data date (omitted on the first available date) |
Data Notes
- Data source: Compiled from daily constituent disclosures published by each ETF's issuing investment trust company. For reference only — the actual holdings are subject to the disclosures published by each issuer / fund prospectus.
- Historical coverage: The start date of coverage varies by ETF and is not a single fixed date. Verified against
0050and00878, data goes back to as early as early 2019 and mid-2020 respectively. Do not assume a uniform coverage start date across ETFs — rely on the actual response. - Trading days without constituent data: Trading days for which the issuer did not provide constituent data will not appear in the response
dataarray. - Weight coverage: This data only covers the ETF's equity holdings. For equity ETFs (passive or active), weight is close to 100% (the remainder being cash). For balanced / multi-asset ETFs, only the equity portion is returned and weights will not sum to 100% (may be around 30% only). For pure bond / futures / commodity ETFs with no equity holdings,
data: []is returned. - Change fields:
quantityChange/weightChangeare calculated against "the ETF's previous date with constituent data," not guaranteed to be the previous trading day. These two fields are omitted on the ETF's first available data date.
Example
- Python
- Node.js
- C#
from fubon_neo.sdk import FubonSDK, Order
sdk = FubonSDK()
accounts = sdk.login("Your ID", "Your password", "Your cert path", "Your cert password")
sdk.init_realtime() # Establish market data connection
reststock = sdk.marketdata.rest_client.stock
## Version 2.2.6 and later using following Exception for error handling
from fubon_neo.sdk import FugleAPIError
try:
response = reststock.ownership.etf_holdings(**{"symbol": "0050", "from": "2026-07-09", "to": "2026-07-09"})
except FugleAPIError as e:
print(f"Error: {e}")
print("------------")
print(f"Status Code: {e.status_code}") # ex: 429
print(f"Response Text: {e.response_text}") # ex: {"statusCode":429,"message":"Rate limit exceeded"}
print(response)
const { FubonSDK } = require('fubon-neo');
const sdk = new FubonSDK();
const accounts = sdk.login("Your ID", "Your Password", "Your Cert Path", "Your Cert Password");
sdk.initRealtime(); // Establish market data connection
const client = sdk.marketdata.restClient
client.stock.ownership.etfHoldings({ symbol: '0050', from: '2026-07-09', to: '2026-07-09' })
.then(data => console.log(data));
using FubonNeo.Sdk;
using FugleMarketData.QueryModels.Stock.Ownership;
var sdk = new FubonSDK();
var result = sdk.Login("Your ID", "Your Password", "Your Cert Path", "Your Cert Password");
sdk.InitRealtime(); // Establish market data connection
var rest = sdk.MarketData.RestClient.Stock;
var etfHoldings = await rest.Ownership.EtfHoldings(new()
{
Symbol = "0050",
From = fromDate,
To = toDate
});
var etfHoldings_cont = etfHoldings.Content.ReadAsStringAsync().Result;
Console.WriteLine(etfHoldings_cont);
Response Body (to save space, components only lists the top 3 constituents, truncated with ...; the actual response includes all constituents for the date. Example based on real production data as of the 2026-07-09 close; the default query range returns 21 trading days):
{
"symbol": "0050",
"type": "EQUITY",
"exchange": "TWSE",
"market": "TSE",
"data": [
{
"date": "2026-07-09",
"components": [
{
"symbol": "2330",
"name": "台積電",
"quantity": 530358242,
"weight": 58.82,
"quantityChange": 370562,
"weightChange": 0.17
},
{
"symbol": "2454",
"name": "聯發科",
"quantity": 32045645,
"weight": 5.76,
"quantityChange": 22388,
"weightChange": -0.09
},
{
"symbol": "2308",
"name": "台達電",
"quantity": 41931322,
"weight": 3.56,
"quantityChange": 29348,
"weightChange": -0.03
}
// ... remaining constituents omitted
]
}
// ... remaining trading days omitted
]
}