ETF & Index Data · 2026-04-24 · 11 min read
台股 ETF 與指數成分股 API:0050、產業分類與輪動策略資料
ETF 與指數成分股資料是台股量化交易、ETF dashboard、universe selection、產業輪動策略與 AI agent 股票研究的重要資料層。對 developer 來說,重點不只是查到 0050 或某個指數有哪些成分股,而是要取得成分股、權重、產業分類、調整日期、rebalancing、成分變更與資料版本,才能把它穩定接進回測與 production workflow。
TL;DR
台股 ETF 與指數成分股 API 應該支援 ETF 基本資料、ETF holdings、指數成分股、權重、產業分類、成分變更、rebalancing date 與 as-of date。對量化交易來說,這些資料最常用來建立股票 universe、做 sector exposure 控制、設計輪動策略,或讓 AI agent 查詢某個 ETF / 指數目前包含哪些股票。
ETF 與指數資料的難點不是欄位很多,而是時間版本。回測不能用今天的 0050 成分股去回測 2020 年策略,否則會產生 look-ahead bias。API 必須清楚標示 as_of_date、effective_date、weight 與 constituent_changes。
為什麼 ETF 與指數成分股 API 重要?
量化研究通常不會直接從全部上市上櫃股票開始,而是先定義 universe。Universe 可以是大型股、某個 ETF 成分股、某個指數成分股、特定產業,或流動性足夠的一組股票。
ETF 與指數成分股 API 可以支援:
- ETF dashboard
- ETF holdings 查詢
- 指數成分股查詢
- 股票 universe selection
- sector exposure 分析
- 產業輪動策略
- ETF 成分股變更追蹤
- 回測資料集建立
- AI agent 股票研究助理
如果你還在理解台股 API 的整體架構,可以先看 台股 API 完整指南。
ETF 資料、指數資料與股票清單有什麼差別?
ETF、指數與股票清單看起來都像一組股票,但資料語意不同。
| 類型 | 說明 | 常見欄位 | 適合用途 |
|---|---|---|---|
| 股票清單 | 可交易股票或商品的基本列表 | symbol, name, market, industry, is_active | 搜尋、資料庫基礎表、universe 初始來源 |
| 指數成分股 | 某個指數在特定日期的成分股 | index_code, constituent_symbol, weight, effective_date | 指數研究、benchmark、universe selection |
| ETF holdings | ETF 持有的標的與權重 | etf_symbol, holding_symbol, weight, shares, market_value | ETF dashboard、持股分析、曝險分析 |
| 產業分類 | 股票所屬產業或 sector | symbol, industry, sector, classification_source | sector exposure、產業輪動、風險控管 |
對資料產品來說,這些資料不應該全部塞在同一個 endpoint 裡。ETF holdings、index constituents 與 stock master 應該有各自清楚的 schema。
ETF holdings API 應該包含哪些欄位?
ETF holdings API 應該描述某檔 ETF 在特定日期持有哪些標的、各自權重是多少,以及資料版本或資料日期。
| Field | Type | Description |
|---|---|---|
| etf_symbol | string | ETF 代號,例如 0050 |
| etf_name | string | ETF 名稱 |
| as_of_date | string | holdings 資料日期 |
| holding_symbol | string | 成分股代號 |
| holding_name | string | 成分股名稱 |
| market | string | 市場別,例如 twse、tpex |
| weight | number | 成分股權重 |
| shares | number | ETF 持有股數,可選 |
| market_value | number | 持股市值,可選 |
| currency | string | 幣別,例如 TWD |
ETF holdings response example
{
"data": [
{
"etf_symbol": "0050",
"etf_name": "Yuanta/P-shares Taiwan Top 50 ETF",
"as_of_date": "2026-04-24",
"holding_symbol": "2330",
"holding_name": "台積電",
"market": "twse",
"weight": 0.61,
"shares": 472160000,
"market_value": 983330000000,
"currency": "TWD"
}
],
"meta": {
"source": "tw-market-data",
"data_type": "etf_holdings",
"timezone": "Asia/Taipei"
}
}上方數值是 schema 示意,不代表實際 holdings。正式 API 應以資料來源與更新時間為準。
指數成分股 API schema
指數成分股 API 的重點是 index code、成分股、權重與生效日期。若要用於回測,還需要查詢歷史成分股,而不是只查最新成分。
Index constituents response example
{
"data": [
{
"index_code": "TW50",
"index_name": "Taiwan 50 Index",
"as_of_date": "2026-04-24",
"effective_date": "2026-04-22",
"constituent_symbol": "2330",
"constituent_name": "台積電",
"market": "twse",
"weight": 0.61,
"sector": "Semiconductors"
}
],
"meta": {
"source": "tw-market-data",
"data_type": "index_constituents",
"timezone": "Asia/Taipei"
}
}欄位設計重點
| 欄位 | 說明 | 為什麼重要 |
|---|---|---|
| index_code | 指數代碼 | 區分不同指數 |
| as_of_date | 查詢資料日期 | 支援歷史查詢與版本控制 |
| effective_date | 成分股變更生效日期 | 避免回測使用未來成分 |
| constituent_symbol | 成分股股票代號 | 用於連接 OHLCV、財報與籌碼資料 |
| weight | 成分股權重 | 用於權重型 universe、sector exposure 與 benchmark |
| sector | 產業或 sector | 用於風險控管與產業輪動 |
0050 成分股資料可以怎麼設計?
0050 是台灣市場常見的大型股 ETF,因此很多研究者會用它作為大型股 universe 的起點。但在 API 設計上,不應該把 0050 特別寫死,而是應該讓所有 ETF 使用同一套 holdings schema。
查詢 0050 holdings endpoint 示意
GET /v1/tw/etfs/0050/holdings?as_of=2026-04-24
GET /v1/tw/etfs/0050/holdings/history?from=2020-01-01&to=2026-04-24上方 endpoint 是示意。實際路徑請以 TW Market Data docs 為準。
這樣使用者可以查 0050,也可以用同一套 endpoint 查其他 ETF。資料產品應該用一致 schema,而不是為每個 ETF 設計一個特殊 case。
產業分類與 sector exposure
ETF 與指數成分股資料通常會和產業分類一起使用。對量化交易來說,產業分類不只是顯示用途,也可以用來控制 portfolio exposure。
Sector exposure example
{
"date": "2026-04-24",
"portfolio": "example_strategy",
"sector_exposure": [
{
"sector": "Semiconductors",
"weight": 0.42
},
{
"sector": "Financials",
"weight": 0.18
},
{
"sector": "Electronics",
"weight": 0.15
}
]
}如果策略只看股票分數而不控制 sector exposure,可能會不小心集中在同一產業。這也是 ETF、指數成分股與產業分類資料在回測中很重要的原因。
Rebalancing、成分變更與 as-of date
ETF 和指數成分股會變動。對回測來說,最危險的錯誤是用最新成分股回測過去資料。這會產生 look-ahead bias,因為策略在歷史某一天使用了當時還不知道的成分股資訊。
API 應該清楚提供:
- as_of_date
- effective_date
- review_date
- added_symbols
- removed_symbols
- old_weight
- new_weight
- data_version
Constituent changes schema
{
"data": [
{
"index_code": "TW50",
"review_date": "2026-03-15",
"effective_date": "2026-03-22",
"change_type": "added",
"symbol": "1234",
"name": "Example Co",
"new_weight": 0.012
},
{
"index_code": "TW50",
"review_date": "2026-03-15",
"effective_date": "2026-03-22",
"change_type": "removed",
"symbol": "5678",
"name": "Old Example Co",
"old_weight": 0.008
}
]
}對 production workflow 來說,成分變更資料應該可以被重跑、被 audit,也能被 backtester 依照歷史日期查詢。
如何用成分股建立 universe selection?
Universe selection 是量化策略的第一步。ETF 與指數成分股資料最常見的用途,就是建立可交易或可研究的股票集合。
Universe schema 示意
{
"universe": "0050_holdings",
"as_of_date": "2026-04-24",
"symbols": [
{
"symbol": "2330",
"name": "台積電",
"market": "twse",
"weight": 0.61,
"sector": "Semiconductors"
}
],
"source": {
"type": "etf_holdings",
"symbol": "0050"
}
}如果你要理解量化研究中的 universe selection,可以參考 台股量化交易入門。
Python 串接 ETF / index constituents API 範例
以下示範如何用 Python 查詢 ETF holdings,並建立一個股票 universe。
import os
import requests
import pandas as pd
API_KEY = os.getenv("TW_MARKET_DATA_API_KEY")
BASE_URL = "https://api.example.com"
headers = {
"Authorization": f"Bearer {API_KEY}"
}
response = requests.get(
f"{BASE_URL}/v1/tw/etfs/0050/holdings",
headers=headers,
params={
"as_of": "2026-04-24"
},
timeout=20
)
response.raise_for_status()
payload = response.json()
holdings = pd.DataFrame(payload["data"])
holdings["as_of_date"] = pd.to_datetime(holdings["as_of_date"])
universe = holdings["holding_symbol"].dropna().unique().tolist()
print(universe[:10])上方 endpoint 是示意。實際路徑請以 TW Market Data docs 為準。
計算 sector exposure
sector_exposure = (
holdings
.groupby("sector", as_index=False)["weight"]
.sum()
.sort_values("weight", ascending=False)
)
print(sector_exposure)這種資料可以接到 dashboard,也可以接到回測中的風險控管模組。
如何把 ETF / 指數資料接進回測?
把 ETF holdings 或 index constituents 接進回測時,最重要的是使用正確的歷史版本。回測日期只能使用當時有效的成分股資料。
Backtest-safe universe query
backtest_date = "2025-06-30"
response = requests.get(
f"{BASE_URL}/v1/tw/etfs/0050/holdings",
headers=headers,
params={
"as_of": backtest_date
},
timeout=20
)
response.raise_for_status()
holdings = pd.DataFrame(response.json()["data"])
universe = holdings["holding_symbol"].tolist()如果用最新 holdings 直接回測過去策略,會讓策略看起來比真實更穩定,因為已經排除了過去被移除的成分股。
如果你要建立完整回測流程,可以參考 Python 台股回測系統實作。
AI agent 如何使用 ETF 與指數資料?
AI agent 可以用 ETF 與指數成分股資料做研究輔助,例如查詢某檔 ETF 目前持有哪些股票、某個 index 的 sector exposure,或比較 ETF holdings 與基本面 / 籌碼資料。
Agent tool schema 示意
{
"name": "get_etf_holdings",
"description": "Get ETF holdings for a Taiwan ETF.",
"parameters": {
"etf_symbol": "0050",
"as_of": "2026-04-24"
}
}Agent response schema 示意
{
"etf_symbol": "0050",
"as_of_date": "2026-04-24",
"data_used": [
"etf_holdings",
"sector_classification"
],
"top_holdings": [
{
"symbol": "2330",
"weight": 0.61
}
],
"sector_exposure": [
{
"sector": "Semiconductors",
"weight": 0.42
}
],
"risk_flags": [
"weights_require_latest_data",
"not_a_trading_signal"
],
"not_investment_advice": true
}這種結構化資料可以讓 agent 做摘要與比較,但不應該讓 agent 用記憶猜 ETF 成分股或權重。
常見資料品質問題
ETF 與指數資料最常見的問題是時間版本、權重、成分變更與分類口徑不清楚。
| 問題 | 影響 | API 應提供的協助 |
|---|---|---|
| 只提供最新成分股 | 回測產生 look-ahead bias | 支援 as_of_date 與 historical constituents |
| 權重更新時間不清楚 | dashboard 和回測使用錯誤權重 | 提供 as_of_date、updated_at |
| ETF holdings 與 index constituents 混淆 | 使用者誤把 ETF 持股當成指數成分 | 分開 endpoint 與 data_type |
| 成分變更沒有記錄 | 無法重建歷史 universe | 提供 constituent changes endpoint |
| 產業分類口徑不一致 | sector exposure 錯誤 | 提供 classification_source |
| 權重加總不等於 1 | portfolio 或 exposure 計算錯誤 | 提供 cash / other holdings 或 metadata |
建議的 API endpoint 設計
以下是 ETF 與指數成分股資料相關 endpoint 的設計示意。
GET /v1/tw/etfs
GET /v1/tw/etfs/{symbol}/profile
GET /v1/tw/etfs/{symbol}/holdings
GET /v1/tw/etfs/{symbol}/holdings?as_of=2026-04-24
GET /v1/tw/indices
GET /v1/tw/indices/{index_code}/constituents
GET /v1/tw/indices/{index_code}/constituents?as_of=2026-04-24
GET /v1/tw/indices/{index_code}/constituent-changes
GET /v1/tw/stocks/{symbol}/sector-classification實際 endpoint 命名不一定要完全相同。重點是 ETF holdings、index constituents、sector classification 與 historical versions 要能被清楚查詢。
上方 endpoint 是示意。實際路徑請以 TW Market Data docs 為準。
如果你要把成分股 universe 和台股歷史價格資料一起回測,可以參考 台股歷史股價 API 設計。
如果你要把 ETF / 指數 universe 再結合營收、EPS、ROE 與現金流因子,可以參考 台股財報 API 教學。
如果你要把 ETF universe 與外資、投信、自營商的資金流一起分析,可參考 三大法人買賣超 API。
FAQ
台股 ETF API 可以取得哪些資料?
台股 ETF API 通常可以取得 ETF 基本資料、持股明細、權重、淨值、折溢價、配息、交易資料與歷史 holdings。實際支援項目取決於 API 供應商與資料授權。
ETF holdings 和指數成分股一樣嗎?
不完全一樣。ETF holdings 是 ETF 實際或揭露的持股資料;指數成分股是指數編製規則下的成分股票。兩者可能相似,但不應在資料模型中混用。
為什麼 index constituents 需要 as_of_date?
因為指數成分股會變動。回測時必須使用當時有效的成分股,而不是最新成分股。`as_of_date` 可以幫助避免 look-ahead bias。
0050 成分股可以用來做量化 universe 嗎?
可以,0050 成分股常被用作大型股 universe 的起點。但正式回測仍需要確認 holdings 的歷史版本、權重、交易日曆、交易成本與流動性條件。
產業分類資料有什麼用途?
產業分類可以用於 sector exposure、產業輪動、風險控管與 portfolio constraints。它也能幫助 AI agent 比較同產業公司的財報、籌碼與技術指標。
AI agent 可以查 ETF 成分股嗎?
可以。AI agent 可以透過 tool calling 查詢 ETF holdings 或 index constituents,並產生結構化摘要。但 agent 不應該自己猜 ETF 成分股或權重,也不應把結果當成投資建議。
下一步
如果你正在建立台股 ETF、指數或 universe selection workflow,建議先處理三件事:
- 1. 區分 ETF holdings、index constituents 與 stock master
- 2. 對所有成分股資料加入 as_of_date 與 effective_date
- 3. 將產業分類與權重接進回測、dashboard 和 AI agent workflow
Need structured Taiwan ETF and index constituent data for your quant workflow, dashboard, or AI agent?
本文討論資料工程、API 設計、ETF / 指數成分股、量化研究與 AI workflow,不構成投資建議。