31 个端点 · 行情 · 基本面 · 筹码面 · 其他
https://api.blave.orgapi-key 与 secret-key 请求头API plan or Blave Agent planstock_id:TWSE(上市)/TPEx(上柜)代码,例如 2330、0050、00878、006208。英文字母与数字(可含点),≤ 8 字符,否则回 400 {"error": "Invalid stock_id"}。start/end:YYYY-MM-DD,含当日。除非该端点另有说明,否则不做格式验证(以字符串比较过滤),所以一律送 YYYY-MM-DD。503 {"error": "Upstream rate limit. Please retry shortly."},稍后重试。batch/<data_type>(每次 ≤ 50 档);不要拿单股端点对整个股票池跑循环。/studio/market/twstock/list 无。
data = requests.get(f"{BASE_URL}/studio/market/twstock/list" , headers=headers, timeout=60).json()["data"]# [{"stock_id": "00400A", "name": "主動國泰動能高息", "close": 14.72, "market": "TWSE",# "industry_code": None, "listing_date": None}, ...] # 2,392 rows in this response{"data": [...]},约 2,400 列(上市+上柜,含 ETF;不含兴柜)。
| 字段 | 类型 | 说明 |
|---|---|---|
stock_id | string | 代码 |
name | string | 名称 |
close | float | null | 最新日收盘价(上游没有数据时为 null,例如暂停交易) |
market | string | TWSE(上市)或 TPEx(上柜) |
industry_code | string | null | TWSE/TPEx 原始的数字产业别代码,原样传回(不解码)。ETF/非公司型证券为 null。常见代码:15 航运业、17 金融保险业、22 生技医疗业、24 半导体业、25 电脑及周边设备业、26 光电业、27 通信网络业、28 电子零组件业、29 电子通路业、30 资讯服务业、31 其他电子业 |
listing_date | string | null | YYYY-MM-DD;ETF/非公司型证券为 null |
只有共用错误(两个市场都失败时回 500)。
[:N] 截断会集中在少数几个产业。/studio/market/twstock/info/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 |
info = requests.get(f"{BASE_URL}/studio/market/twstock/info/2330" , headers=headers, timeout=30).json()["data"]# {"stock_id": "2330", "name": "台積電", "close": 2410.0, "industry_code": "24", "listing_date": "1994-09-05"}{"stock_id": "<stock_id>", "data": {...}};data 的字段与 /list 的一列相同。
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | 格式检查未通过 |
| 404 | {"error": "Stock not found"} | 不是目前上市柜的证券 |
/list 共用同一份缓存。/studio/market/twstock/price/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 上市或上柜股票/ETF 代码 | 英文字母/数字(可含点),≤ 8 字符,例如 2330、0050、00878、006208 | |
startstring · query | 起始日,含当日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日,含当日 | YYYY-MM-DD | 最新一天 |
response = requests.get(f"{BASE_URL}/studio/market/twstock/price/2330" , headers=headers, timeout=60)data = response.json()["data"] # no start/end → full history, 8,069 rows# [{"date": "1994-10-01", "stock_id": "2330", "open": 171.0, "high": 172.0,# "low": 171.0, "close": 172.0, "spread": 1.0,# "volume": 1660506, "turnover_value": 284858008, "turnover_count": 684},# {"date": "1994-10-03", "stock_id": "2330", "open": 172.0, "high": 173.0,# "low": 171.0, "close": 172.0, "spread": 0.0,# "volume": 1560000, "turnover_value": 268084000, "turnover_count": 711}, ...]{"stock_id": "<stock_id>", "data": [ ... ]},依 date 由旧到新排序。
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
date | string | YYYY-MM-DD | 交易日 |
stock_id | string | — | 股票代码 |
open / high / low / close | float | 元 | 未还原价格 |
spread | float | 元 | 与前一日收盘价的差额 |
volume | int | 股 | 成交股数 |
turnover_value | int | 元 | 成交金额 |
turnover_count | int | 笔 | 成交笔数 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | stock_id 格式检查未通过 |
| 404 | {"error": "No data found for stock_id: <stock_id>"} | 未知代码/上游没有数据 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽,稍后重试 |
start/end 不做格式验证:格式错误的值会改用字符串比较过滤,而不是回 400,所以一律送 YYYY-MM-DD。price_adj;这个端点是未还原价格。batch/price(每次 ≤ 50 档),不要对这个端点跑循环。/studio/market/twstock/price_adj/<stock_id> 同 /price/<stock_id>。
params = {"start": "2020-01-01", "end": "2024-12-31"}data = requests.get(f"{BASE_URL}/studio/market/twstock/price_adj/2330" , headers=headers, params=params, timeout=60).json()["data"]形状与字段同 /price/<stock_id>;open/high/low/close 是还原后的价格,volume/turnover_* 与原始序列相同。
同 /price/<stock_id>。
/price 序列有新数据时重建。/studio/market/twstock/quote/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/quote/2330" , headers=headers, timeout=30).json()["data"]# {"open": 2415.0, "high": 2465.0, "low": 2415.0, "close": 2445.0,# "change_price": -20.0, "change_rate": -0.81, "average_price": 2432.58,# "volume": 4245, "total_volume": 26403, "amount": 10379025000, "total_amount": 64227410000,# "yesterday_volume": 27390, "buy_price": 2445.0, "buy_volume": 17,# "sell_price": 2450.0, "sell_volume": 11, "volume_ratio": 0.96,# "quote_time": "2026-07-03 14:30:00", "stock_id": "2330", "tick_type": 2}{"stock_id": "<stock_id>", "data": {...}};data 是扁平对象。
| 字段 | 类型 | 说明 |
|---|---|---|
open / high / low / close | float | 今日至今的 OHLC |
change_price / change_rate | float | 与前一日收盘价的涨跌(元/%) |
average_price | float | 成交均价 |
volume | int | 最新一笔的成交量 |
total_volume | int | 今日累计成交量 |
amount / total_amount | float | 最新一笔/累计成交金额 |
yesterday_volume | int | 前一日成交量 |
buy_price / buy_volume | float / int | 最佳买价 |
sell_price / sell_volume | float / int | 最佳卖价 |
volume_ratio | float | 量比 |
quote_time | string | YYYY-MM-DD HH:MM:SS,是完整时间戳,不像其他端点只有 date |
stock_id | string | 代码 |
tick_type | int | 0 无法判断、1 卖盘成交、2 买盘成交 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | 格式检查未通过 |
| 404 | {"error": "No data found for stock_id: <stock_id>"} | 没有报价 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/studio/market/twstock/quote | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idsstring · query必填 | 代码 | 逗号分隔,≤ 50 档 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/quote" , headers=headers, params={"stock_ids": "2330,2317"}, timeout=30).json()["data"]# {"2330": {...}, "2317": {...}}{"data": {"<stock_id>": {...quote fields...}, ...}};字段同 /quote/<stock_id>。没有报价的代码不会出现。
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "stock_ids parameter required"} | 缺少 |
| 400 | {"error": "stock_ids exceeds max 50 per request"} | 超过上限 |
| 400 | {"error": "Invalid stock_id in list"} | 有代码格式检查未通过 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/studio/market/twstock/quote/all 无。
rows = requests.get(f"{BASE_URL}/studio/market/twstock/quote/all" , headers=headers, timeout=30).json()["data"]{"data": [{...quote fields...}, ...]}(约 2,800 列);字段同 /quote/<stock_id>。
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/studio/market/twstock/minute/ohlcv/<stock_id>/<schema> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 目前上市柜的 TWSE/TPEx 代码,或 TAIEX(加权指数) | |
schemastring · path必填 | K 棒周期 | 1m, 5m, 15m, 30m, 60m, 1d | |
startstring · query | 起始日 | YYYY-MM-DD | end − 该周期的最大区间 |
endstring · query | 结束日(含当日) | YYYY-MM-DD | 今天(UTC) |
adjuststring · query | 1 = 还原(后复权)OHLC,因子同 /price_adj;volume 一律不还原 | 0, 1, true, false | 0 |
每次请求的最大区间(end − start):1m 31 天 · 5m 62 天 · 15m 93 天 · 30m 186 天 · 60m 365 天 · 1d 3650 天。
body = requests.get(f"{BASE_URL}/studio/market/twstock/minute/ohlcv/2330/1m" , headers=headers, params={"start": "2026-08-06", "end": "2026-08-06"}, timeout=60).json()# {"stock_id": "2330", "schema": "1m", "data": [# {"close": 2385.0, "high": 2395.0, "low": 2385.0, "open": 2395.0, "ts": "2026-08-06 01:00:00+00:00", "volume": 2540}, ...]}{"stock_id", "schema", "data": [...]}.
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
ts | string | UTC ISO 格式 | K 棒开始时间(以分钟起点标记);台北时间 13:30 那根是收盘集合竞价 |
open / high / low / close | float | 元 | 价格 |
volume | int | 张,不是股 | 成交量。TAIEX 的 K 棒在每个周期都是 volume: 0:指数没有成交量,所以不提供;不要当成成交金额来读 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id (must be a listed TWSE/TPEx security)"} | 未上市柜 |
| 400 | {"error": "Invalid schema. Allowed: [...]"} | 周期不对 |
| 400 | {"error": "Invalid adjust (use 0 or 1)"} | adjust 不对 |
| 400 | {"error": "Invalid date format. Use YYYY-MM-DD"} | 日期格式错误 |
| 400 | {"error": "date_range_too_large", "message": "...", "max_days": <n>} | 区间超过上限 |
| 503 | {"error": "market data temporarily unavailable"} | 数据库读取失败 |
| 503 | {"error": "adjust factors temporarily unavailable"} | adjust=1 但取不到还原因子:绝不会默默改给未还原数据 |
minute/ohlcv/symbols。200 与 []。/quote/<stock_id>。/studio/market/twstock/minute/ohlcv/symbols 无。
covered = requests.get(f"{BASE_URL}/studio/market/twstock/minute/ohlcv/symbols" , headers=headers, timeout=30).json()["data"]{"data": ["2330", "TAIEX", ...]}:已经有分钟线数据的代码(目前上市柜的股票加上 TAIEX),已排序。
只有共用错误。
/studio/market/twstock/kbar/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 目前上市柜的 TWSE/TPEx 代码,或 TAIEX | |
startstring · query | 起始日 | YYYY-MM-DD | 今天 − 6 天 |
endstring · query | 结束日;end − start ≤ 31 天 | YYYY-MM-DD | 今天 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/kbar/2330" , headers=headers, params={"start": "2026-08-03", "end": "2026-08-07"}, timeout=60).json()["data"]{"stock_id", "data": [...]},由旧到新。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | YYYY-MM-DD(台北时间) |
minute | string | HH:MM:SS 台北时间,K 棒开始时间(09:00–13:30) |
stock_id | string | 代码 |
open / high / low / close | float | 元 |
volume | int | 张 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id (must be a listed TWSE/TPEx security)"} | 未上市柜 |
| 400 | {"error": "Date range exceeds 31 days"} | 区间太长,或日期格式错误 |
minute/ohlcv/<stock_id>/1m。上市柜股票没有分钟数据时回 [](这个端点不会触发回补)。minute/ohlcv/symbols 涵盖的代码有数据。/studio/market/twstock/market_value/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日 | YYYY-MM-DD | 最新 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/market_value/2330" , headers=headers, params={"start": "2026-01-01"}, timeout=60).json()["data"]{"stock_id", "data": [{"date", "stock_id", "market_value"}]};market_value 单位为元。
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
/studio/market/twstock/market_value/all | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
topint · query | 只留市值前 N 名 | 1–3000 | 全部(约 2,400) |
body = requests.get(f"{BASE_URL}/studio/market/twstock/market_value/all" , headers=headers, params={"top": 10}, timeout=60).json()# {"date": "2026-09-17", "twse_ex_etf_market_value": 150952470507848,# "data": [{"is_etf": false, "market": "TWSE", "market_value": 62885997412475,# "name": "台積電", "rank": 1, "stock_id": "2330"},# ...,# {"is_etf": true, "market": "TWSE", "market_value": 2383312875000,# "name": "元大台灣50", "rank": 6, "stock_id": "0050"}, ...]}# Index weight of a 上市 non-ETF stock (works with any `top`, the denominator is whole-market)row = body["data"][0] # 2330 — market "TWSE", is_etf falseshare = row["market_value"] / body["twse_ex_etf_market_value"]# ETFs rank alongside stocks (0050 is rank 6) — filter them with `is_etf`. Never by code prefix,# and never by re-fetching a classification: `is_etf` already IS that classification.rows = requests.get(f"{BASE_URL}/studio/market/twstock/market_value/all" , headers=headers, params={"top": 100}, timeout=60).json()["data"]top50 = [r["stock_id"] for r in rows if not r["is_etf"]][:50] # ETF-free market-cap top 50tpex_only = [r["stock_id"] for r in rows if r["market"] == "TPEx"] # board filter is exact{"date": "YYYY-MM-DD", "twse_ex_etf_market_value": int, "data": [...]},依市值由大到小排序。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 实际采用的基准日(最新公布日;可能比今天晚一天) |
twse_ex_etf_market_value | int | 元。同一基准日 market == "TWSE" 且非 ETF 各列的加总。这是全市场分母,不会因 top 而缩小 |
data[].rank | int | 名次,从 1 起算 |
data[].stock_id | string | 代码 |
data[].name | string | 名称 |
data[].market | string | "TWSE"(上市)或 "TPEx"(上柜),取自 TWSE/TPEx 的上市柜名册 |
data[].market_value | int | 元 |
data[].is_etf | bool | 排行中的 ETF 为 true(2026-09-17 的 2,370 列中有 359 列)。false 代表「不在 ETF 集合里」,不代表「确认不是 ETF」:没有产业类别的证券(例如 REIT 01010T)会是 false,而且仍算在 twse_ex_etf_market_value 里 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "top must be an integer between 1 and 3000"} | top 不对 |
| 404 | {"error": "No recent market value data available"}(或上市柜清单不完整的信息) | 没有近期数据 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/market_value/<stock_id> 跑循环。rank 与 twse_ex_etf_market_value 的母体不同。rank 是全市场排名(上市+上柜,含 ETF),加上分母之后也没有改变。分母只算上市、排除 ETF(industry_category 属于 {ETF, 上櫃ETF, 上櫃指數股票型基金(ETF)});REIT 与特别股没有排除。所以 market_value / twse_ex_etf_market_value 只有在该列 market 为 "TWSE" 且不是 ETF 时才是指数权重,上柜或 ETF 的列除以这个分母不是权重;rank 则仍是全市场排名。不要把两者当成同一个排行来读。market 是挂牌板别标记,不是 ETF 旗标,is_etf 才是 ETF 旗标。要排除 ETF 的股票池就用它。不要从 stock_id 开头推断 ETF(00 是市场惯例而不是规格,而且会漏掉 REIT 01xxxT),也不要再从别处抓一次分类。is_etf 正是 twse_ex_etf_market_value 计算时用的判准,所以用 is_etf 筛选的结果和分母不可能对不上。/studio/market/twstock/per/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日 | YYYY-MM-DD | 最新 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/per/2330" , headers=headers, params={"start": "2026-01-01", "end": "2026-07-22"}, timeout=60).json()["data"]# [{"date": "2026-07-21", "stock_id": "2330", "dividend_yield": 0.95, "PER": 34.87, "PBR": 11.05}, ...]{"stock_id", "data": [...]}.
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 交易日 |
stock_id | string | 代码 |
dividend_yield | float | 殖利率(%) |
PER | float | 本益比 |
PBR | float | 股价净值比 |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
batch/per。/studio/market/twstock/financials/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 2013-01-01 |
endstring · query | 结束日 | YYYY-MM-DD | 今天 |
import pandas as pddata = requests.get(f"{BASE_URL}/studio/market/twstock/financials/2330" , headers=headers, params={"start": "2022-01-01", "end": "2024-12-31"}, timeout=30).json()["data"]# [{"date": "2022-03-31", "stock_id": "2330", "type": "Revenue", "value": 491075000000.0, "origin_name": "營業收入"}, ...]wide = pd.DataFrame(data).pivot_table(index="date", columns="type", values="value", aggfunc="first"){"stock_id", "data": [...]},长格式(每季每个科目一列)。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 季末日(03-31/06-30/09-30/12-31) |
stock_id | string | 代码 |
type | string | 科目代码,例如 Revenue、GrossProfit、OperatingIncome、NetIncome、EPS、TAX、OtherComprehensiveIncome |
value | float | 数值(元;EPS 为每股元) |
origin_name | string | 中文科目名称,遇到不认得的 type 代码时用它辨识 |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
start 默认为 2013-01-01;送更早的 start 就会拿到更早的数据(2330 最早到 2000-06-30)。/studio/market/twstock/balance_sheet/<stock_id> 同 /financials/<stock_id>。
data = requests.get(f"{BASE_URL}/studio/market/twstock/balance_sheet/2330" , headers=headers, params={"start": "2022-01-01"}, timeout=30).json()["data"]长格式同 /financials/<stock_id>。主要 type 代码:CashAndCashEquivalents、TotalAssets、TotalLiabilities、TotalEquity。结尾为 _per 的代码是占总资产的百分比。
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
start 默认为 2013-01-01;送更早的 start 就会拿到更早的数据(2330 最早到 2012-12-31)。/studio/market/twstock/cashflow/<stock_id> 同 /financials/<stock_id>。
import pandas as pddata = requests.get(f"{BASE_URL}/studio/market/twstock/cashflow/2330" , headers=headers, params={"start": "2022-01-01"}, timeout=30).json()["data"]cfo = (pd.DataFrame(data).query("type == 'CashFlowsFromOperatingActivities'") .assign(date=lambda d: pd.to_datetime(d["date"])).set_index("date")["value"].sort_index())cfo_q = cfo - cfo.groupby(cfo.index.year).shift(1).fillna(0) # YTD → single quarter长格式同 /financials/<stock_id>。主要 type 代码(上游数据集自己的代码;完整集合依公司与年度而异,以回应内容为准,下表没有的用 origin_name 判读)。筛选时用 type,不要用 origin_name:同一个代码的中文名称在不同年度会在全形与半形括号之间切换:
type | origin_name |
|---|---|
CashFlowsFromOperatingActivities | 营业活动之净现金流入(流出) |
CashProvidedByInvestingActivities | 投资活动之净现金流入(流出) |
CashFlowsProvidedFromFinancingActivities | 筹资活动之净现金流入(流出) |
PropertyAndPlantAndEquipment | 取得不动产、厂房及设备(资本支出,负值) |
Depreciation / AmortizationExpense | 折旧费用 / 摊销费用 |
CashBalancesIncrease | 本期现金及约当现金增加(减少)数 |
CashBalancesBeginningOfPeriod / CashBalancesEndOfPeriod | 期初(年初)/ 期末现金及约当现金余额 |
流量科目是年初至今(YTD)累计,照台湾申报方式:03-31 那列只有 Q1,06-30 是 Q1–Q2,09-30 是 Q1–Q3,12-31 是全年。要单季数字就减掉同年前一季(Q1 不用减),所以 start 要从 1 月开始抓。CashBalancesEndOfPeriod 是季末余额;CashBalancesBeginningOfPeriod 是年初余额。这个端点没有 period 参数,一律回 YTD(?period=quarter 单季检视只存在于网页图表路由,这里没有)。
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
start 默认为 2013-01-01;送更早的 start 就会拿到更早的数据(2330 最早到 2012-03-31)。/studio/market/twstock/monthly_revenue/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 2000-01-01 |
endstring · query | 结束日 | YYYY-MM-DD | 今天 |
import pandas as pddata = requests.get(f"{BASE_URL}/studio/market/twstock/monthly_revenue/2330" , headers=headers, params={"start": "2024-01-01", "end": "2024-12-31"}, timeout=30).json()["data"]df = pd.DataFrame(data).sort_values(["revenue_year", "revenue_month"])df["yoy_pct"] = df["revenue"].pct_change(periods=12) * 100# [{"date": "2024-01-01", "stock_id": "2330", "country": "Taiwan", "create_time": "",# "revenue": 176299866000, "revenue_year": 2023, "revenue_month": 12},# {"date": "2024-02-01", "stock_id": "2330", "country": "Taiwan", "create_time": "",# "revenue": 215785127000, "revenue_year": 2024, "revenue_month": 1}, ...]{"stock_id", "data": [...]},每月一列。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 营收月份的下一个月的第一天:2024-01-01 那列是 revenue_year: 2023、revenue_month: 12。绝不要拿它当营收期间 |
stock_id | string | 代码 |
country | string | 市场,观察到的值是 Taiwan |
create_time | string | 每一列都观察到是空字符串("") |
revenue | int | 月营收,单位为元,不是千元。这是从数量级推得的,上游没有注明:2330 的 revenue_year 2024, revenue_month 1 回 215785127000,只有读成元(NT$215.8bn)才是合理的数字 |
revenue_month | int | 营收月份(1–12),营收期间看这个,不要看 date |
revenue_year | int | 营收年度 |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
/studio/market/twstock/ratios/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始季末日 | YYYY-MM-DD | 2013-01-01 |
endstring · query | 结束季末日 | YYYY-MM-DD | 今天 |
import pandas as pddata = requests.get(f"{BASE_URL}/studio/market/twstock/ratios/2330" , headers=headers, params={"start": "2024-01-01"}, timeout=30).json()["data"]# [..., {"date": "2026-06-30", "stock_id": "2330",# "gross_margin_q": 67.7207, "gross_margin_ttm": 64.2302, "operating_margin_q": 60.3443, "operating_margin_ttm": 56.1009,# "net_margin_q": 55.6354, "net_margin_ttm": 50.3717, "roe_q": 11.3934, "roe_ttm": 40.3342, "roa_q": 7.8372, "roa_ttm": 27.3074,# "eps_q": 27.25, "eps_ttm": 86.28, "eps_yoy_q": 77.4089, "eps_yoy_ttm": 53.2232,# "revenue_yoy_q": 36.0453, "revenue_yoy_ttm": 30.5567, "revenue_qoq_q": 12.0163, "revenue_qoq_ttm": 8.2017,# "debt_ratio": 30.9438, "current_ratio": 245.7635, "quick_ratio": 225.0114, "equity_multiplier": 1.4481,# "interest_coverage_q": 280.5515, "interest_coverage_ttm": 227.0232,# "inventory_turnover_q": 1.1767, "inventory_turnover_ttm": 4.6058, "cfo_to_net_income_q": 1.1084, "cfo_to_net_income_ttm": 1.1779,# "fcf_q": 287363030000.0, "fcf_ttm": 1143556366000.0, "fcf_per_share_q": 11.0827, "fcf_per_share_ttm": 44.1036, ...}]df = pd.DataFrame(data).assign(date=lambda d: pd.to_datetime(d["date"])).set_index("date"){"stock_id", "data": [...]},宽格式:每季一列,由旧到新,每个比率一栏。每个比率都是四舍五入到 4 位小数的 float,或 null。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 季末日(03-31/06-30/09-30/12-31),不是财报公开的日期 |
stock_id | string | 代码 |
<ratio>_q | float | null | 单季 |
<ratio>_ttm | float | null | 近四季(四个单季加总);四季中任一季缺数据就是 null |
debt_ratio, current_ratio, quick_ratio, equity_multiplier | float | null | 期末资产负债表比率,没有后缀 |
<ratio>(每个都有 _q 与 _ttm 两种):
| 类别 | 比率 | 单位 |
|---|---|---|
| 获利能力 | gross_margin, operating_margin, pretax_margin, net_margin, opex_ratio, roe, roa | %(已乘 100) |
| 每股 | eps, revenue_per_share, fcf_per_share | 每股元 |
| 成长 | revenue_yoy, revenue_qoq, operating_income_yoy, net_income_yoy, eps_yoy | %(已乘 100) |
| 结构 | interest_coverage | 倍 |
| 经营效率 | receivable_turnover, inventory_turnover, asset_turnover, cfo_to_net_income | 倍 |
| 现金流量 | fcf | 元,原始金额(不是千元) |
没有后缀的字段:debt_ratio、current_ratio、quick_ratio 是 %(已乘 100,流动比率 2.46 倍会回 245.7635);equity_multiplier 是倍数。
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | 代码格式检查未通过 |
| 404 | {"error": "No data found for stock_id: <id>"} | 这个代码没有财报(例如 0050/00878 这类 ETF),或 start–end 范围内没有数据 |
| 503 | {"error": "Data temporarily unavailable. Please retry shortly."} | 比率数据库还没准备好,稍后重试,绝不要当成「没有数据」 |
null(没有毛利率、流动比率等)。date 对齐会有前视偏差。null,绝不会是 0。per/<stock_id>),以及月营收相关比率(自己用 monthly_revenue/<stock_id> 算年增/月增)。GET /studio/market/twstock/batch/ratios?stock_ids=...(每次 ≤ 50 档)。start 也拿不到更早的数据。/studio/market/twstock/dividend/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 目前上市柜的代码(4–6 位数字,结尾可带一个英文字母) | |
startstring · query | 起始生效日 | 严格 YYYY-MM-DD | 完整历史 |
endstring · query | 结束生效日 | 严格 YYYY-MM-DD | 完整历史 |
区间过滤用三层递补的生效日:有 cash_ex_date 用它,否则 stock_ex_date,再否则 record_date;刚公告、还没有除息日的事件也会出现。
data = requests.get(f"{BASE_URL}/studio/market/twstock/dividend/2330" , headers=headers, params={"start": "2025-01-01", "end": "2025-12-31"}, timeout=30).json()["data"]# [{"record_date": "2025-03-24", "period": "113年第3季", "announce_date": "2025-03-03",# "cash_ex_date": "2025-03-18", "stock_ex_date": "", "pay_date": "2025-04-10",# "cash": 4.50002042, "stock": 0.0, "stock_ratio": 0.0}, ...]{"stock_id", "data": [...]},每笔公告一列。
| 字段 | 类型 | 说明 |
|---|---|---|
record_date | string | 权利分派基准日 YYYY-MM-DD |
period | string | 股利所属期间,是不透明的标签(114年第3季、113、不適用…);当字符串比较,不要解析成年份 |
announce_date | string | 公告日;不明时为 "" |
cash_ex_date | string | 除息交易日;没有或未定时为 "" |
stock_ex_date | string | 除权交易日;没有时为 "" |
pay_date | string | 现金股利发放日;不明时为 "" |
cash | float | 每股现金股利(元,盈余+公积) |
stock | float | 每股股票股利(元面额,盈余+公积) |
stock_ratio | float | stock / 10,即拆分式的调整比例 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | 格式检查未通过 |
| 400 | {"error": "Invalid start date, expected YYYY-MM-DD"}(或 end) | 日期格式错误 |
| 404 | {"error": "No data found for stock_id: <id>"} / {"error": "No dividend records for stock_id: <id>"} | 未上市柜,或完全没有股利纪录 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
cash == 0 且 stock == 0)会保留,代表公告不分派。2330 的完整历史查询最后一列比请求日还晚一周。只要过去的事件就自己依日期过滤。200 + [](与 404 不同)。404。/studio/market/twstock/news/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 今天 − 6 天 |
endstring · query | 结束日;end − start ≤ 31 天 | YYYY-MM-DD | 今天 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/news/2330" , headers=headers, params={"start": "2026-08-01", "end": "2026-08-07"}, timeout=60).json()["data"]{"stock_id", "data": [...]},每天多则新闻(含周末)。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 发布时间 |
stock_id | string | 代码 |
title | string | 标题 |
source | string | 发布来源 |
link | string | 网址 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Date range exceeds 31 days"} 或日期解析错误的信息 | 区间太长/日期格式错误 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
[]。/studio/market/twstock/institutional/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日 | YYYY-MM-DD | 最新 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/institutional/2330" , headers=headers, params={"start": "2024-01-01", "end": "2024-12-31"}, timeout=60).json()["data"]# [{"date": "2024-01-02", "stock_id": "2330", "foreign_buy": 28464159, "foreign_sell": 47404324,# "trust_buy": 5553520, "trust_sell": 269712, "dealer_self_buy": 452000, "dealer_self_sell": 366190,# "dealer_hedge_buy": 942546, "dealer_hedge_sell": 780090,# "foreign_dealer_self_buy": 0, "foreign_dealer_self_sell": 0}, ...]{"stock_id", "data": [...]},宽格式,每天一列。所有数值单位都是股。
| 字段 | 说明 |
|---|---|
date, stock_id | 日期、代码 |
foreign_buy / foreign_sell | 外资(不含外资自营商) |
trust_buy / trust_sell | 投信 |
dealer_self_buy / dealer_self_sell | 自营商自行买卖 |
dealer_hedge_buy / dealer_hedge_sell | 自营商避险 |
foreign_dealer_self_buy / foreign_dealer_self_sell | 外资自营商(多半是 0) |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
*_buy − *_sell。GET /studio/market/twmarket/institutional)的分组方式不同,见该节。/studio/market/twstock/margin/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日 | YYYY-MM-DD | 最新 |
import pandas as pddata = requests.get(f"{BASE_URL}/studio/market/twstock/margin/2330" , headers=headers, params={"start": "2024-01-01"}, timeout=60).json()["data"]df = pd.DataFrame(data)df["margin_util"] = df["margin_balance"] / df["margin_limit"] # 融資使用率{"stock_id", "data": [...]},每天一列。数值单位是张,不是股,已对照 TWSE MI_MARGN 验证:2026-09-15 的 2330 回 margin_balance: 29282 与 margin_limit: 6483092,与 TWSE 当日公布的今日余额 29,282、次一营业日限额 6,483,092 完全相符。每一列都带自己的 date 与 stock_id;读完整历史(不带 start/end)时,每个数字都要取自同一列:margin_limit 每天重新公布,会随时间改变。
| 字段 | 说明 |
|---|---|
margin_buy / margin_sell | 融资买进/卖出 |
margin_cash_repay | 融资现金偿还 |
margin_balance / margin_prev_balance | 融资今日/前日余额 |
margin_limit | 融资限额,即 TWSE 在该列日期公布的次一营业日限额,也就是适用于下一个营业日的上限(2330 在 2026-09-15 为 6,483,092 张) |
short_buy / short_sell | 融券买进/卖出 |
short_cash_repay | 融券现金偿还 |
short_balance / short_prev_balance | 融券今日/前日余额 |
short_limit | 融券限额 |
offset_loan_short | 资券相抵 |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
/studio/market/twstock/gov_bank/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 今天 − 6 天 |
endstring · query | 结束日;end − start ≤ 31 天 | YYYY-MM-DD | 今天 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/gov_bank/2330" , headers=headers, params={"start": "2026-08-01", "end": "2026-08-07"}, timeout=60).json()["data"]{"stock_id", "data": [...]},每天最多 8 列(每家行库一列),依日期、行库排序。
| 字段 | 说明 |
|---|---|
date, stock_id | 日期、代码 |
bank_name | 行库 |
buy / sell | 买进/卖出股数 |
buy_amount / sell_amount | 买进/卖出金额(元) |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Date range exceeds 31 days"} 或日期解析错误的信息 | 区间太长/日期格式错误 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/studio/market/twstock/lending/<stock_id> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
startstring · query | 起始日 | YYYY-MM-DD | 完整历史 |
endstring · query | 结束日 | YYYY-MM-DD | 最新 |
data = requests.get(f"{BASE_URL}/studio/market/twstock/lending/2330" , headers=headers, params={"start": "2026-08-01"}, timeout=60).json()["data"]{"stock_id", "data": [...]},每天多列。
| 字段 | 说明 |
|---|---|
date, stock_id | 日期、代码 |
transaction_type | 競價 / 議借 |
volume | 成交量 |
fee_rate | 借券费率 |
close | 收盘价 |
original_return_date | 原始还券日 |
original_lending_period | 原始借券期间 |
400 stock_id 无效、404 没有数据、503 上游配额耗尽。
/studio/market/twstock/broker/search | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
namestring · query必填 | 要搜寻的分点名称 | 任意子字符串,不分大小写 |
rows = requests.get(f"{BASE_URL}/studio/market/twstock/broker/search" , headers=headers, params={"name": "松山"}, timeout=30).json()["data"]# [{"broker_id": "9217", "broker_name": "凱基-松山"}, ...]{"query": "<name>", "data": [{"broker_id", "broker_name"}]}.
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "name parameter required"} | 缺少 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 上游配额耗尽 |
/studio/market/twstock/broker/stock/<stock_id> 查单日送 date,查区间送 start(+ end);两者都送时以 start 为准。
| 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
stock_idstring · path必填 | 代码 | 见本类别共通规则 | |
datestring · query | 单日 | YYYY-MM-DD | 今天 |
startstring · query | 区间起点 | YYYY-MM-DD | |
endstring · query | 区间终点;区间 ≤ 366 天(含头尾) | YYYY-MM-DD | start |
rows = requests.get(f"{BASE_URL}/studio/market/twstock/broker/stock/2330" , headers=headers, params={"start": "2026-08-03", "end": "2026-08-07"}, timeout=60).json()["data"]{"stock_id", "data": [...]},每个分点每天一列。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 交易日 |
stock_id | string | 代码 |
broker_id | string | 分点代码(可能含英文字母,例如 920A) |
broker_name | string | 分点名称 |
price | float | 成交量加权平均价 |
buy / sell | int | 买进/卖出股数 |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid stock_id"} | 格式检查未通过 |
| 400 | {"error": "Invalid date (YYYY-MM-DD)"} | 日期格式错误 |
| 400 | {"error": "start/end range is <n> days; max 366 (inclusive) — split into smaller ranges"} | 区间太长 |
| 503 | {"error": "Upstream rate limit. Please retry shortly."} | 数据暂时无法取得,请重试;不要当成「没有成交」 |
200 + []。start/end 设 2026-09-06 → 2026-09-13,broker/stock/<stock_id> 与 broker/trader/<trader_id> 都回了涵盖五个交易日的数据。/studio/market/twstock/broker/trader/<trader_id> date/start/end 规则同 /broker/stock/<stock_id>。
| 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
trader_idstring · path必填 | 分点代码,从 /broker/search 取得 | 英文字母、数字、-(例如 9217、920A) | |
datestring · query | 单日 | YYYY-MM-DD | 今天 |
startstring · query | 区间起点 | YYYY-MM-DD | |
endstring · query | 区间终点;区间 ≤ 366 天(含头尾) | YYYY-MM-DD | start |
rows = requests.get(f"{BASE_URL}/studio/market/twstock/broker/trader/9217" , headers=headers, params={"date": "2026-08-07"}, timeout=60).json()["data"]{"trader_id", "data": [...]},每档股票每天一列;字段为 date、broker_id、broker_name、stock_id、price、buy、sell(同 /broker/stock)。
同 /broker/stock/<stock_id>,另外代码错误时回 400 {"error": "Invalid trader_id"}。
/studio/market/twstock/alerts 给 date,或 start/end,或都不给(= 今天,台北时间)。
| 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
datestring · query | 单日:当天生效中的处置,以及当天公告的注意 | 严格 YYYY-MM-DD;不能与 start/end 同时使用 | |
startstring · query | 区间第一天 | 严格 YYYY-MM-DD | 有 stock_id 时为 2001-01-01,否则为 end − 365 天 |
endstring · query | 区间最后一天(含当日) | 严格 YYYY-MM-DD | 今天(start 较晚时改用它) |
kindstring · query | 公告类型 | disposal(处置)、notice(注意) | 两者 |
marketstring · query | 交易所 | twse, tpex | 两者 |
stock_idstring · query | 单一代码;不受 366 天上限限制 | 见本类别共通规则 | 全部 |
区间的意思:处置的期间(start–end)与查询区间有重叠就回传,注意则是公告 date 落在区间内才回传。不带 stock_id 时区间最多 366 天(含头尾),全市场更长的区间要拆开查(一次查一个日历年刚好放得下)。与本类别的默认不同,start/end/date 都会严格验证。
# disposals in force on one daydata = requests.get(f"{BASE_URL}/studio/market/twstock/alerts" , headers=headers, params={"date": "2026-10-13", "kind": "disposal"}, timeout=30).json()["data"]# [..., {"date": "2026-10-12", "stock_id": "5228", "stock_name": "鈺鎧", "market": "tpex",# "kind": "disposal", "count": 2, "start": "2026-10-13", "end": "2026-10-19",# "condition": "連續3個營業日", "measure": "第一次處置", "match_minutes": 2,# "reason": "* 公布日期:115/10/12\n* 證券代號:5228\n…", "close": 59.6, "pe": 29.22},# {"date": "2026-10-12", "stock_id": "2492", "stock_name": "華新科", "market": "twse",# "kind": "disposal", "count": 8, "start": "2026-10-13", "end": "2026-10-19",# "condition": "連續三次", "measure": "第一次處置", "match_minutes": 2,# "reason": "1處置原因:該有價證券之交易,連續三個營業日達本公司「公布注意交易資訊」標準。\n2處置期間:…", "close": None, "pe": None}, ...] # 36 rows# notices announced on one daynotes = requests.get(f"{BASE_URL}/studio/market/twstock/alerts" , headers=headers, params={"date": "2026-10-12", "kind": "notice"}, timeout=30).json()["data"]# [..., {"date": "2026-10-12", "stock_id": "5228", "stock_name": "鈺鎧", "market": "tpex",# "kind": "notice", "count": 15, "start": None, "end": None, "condition": "第一款、第三款、第四款",# "measure": None, "match_minutes": None,# "reason": "最近六個營業日(含當日)累積之最後成交價漲幅達32.63%(第一款)\n…", "close": 59.6, "pe": 29.22}, ...]# one stock's disposal history (no range cap with stock_id)hist = requests.get(f"{BASE_URL}/studio/market/twstock/alerts" , headers=headers, params={"stock_id": "2492", "kind": "disposal", "start": "2001-01-01"}, timeout=30).json()["data"]# 10 rows: 2001-11-23~2001-11-29 收足五成款券 (match_minutes None), 2018-05-08~2018-05-21 第一次處置 (5), …,# 2026-10-13~2026-10-19 第一次處置 (2){"start", "end", "data": [...]};start/end 回显实际采用的区间(送 date 时两者都等于 date)。各列依 date、market、kind、stock_id 排序。每则公告一列。
| 字段 | 类型 | 说明 |
|---|---|---|
date | string | 公告日 YYYY-MM-DD(处置从下一个交易日起生效) |
stock_id | string | 代码,包含权证、ETF 与可转债(例如 037060、45402) |
stock_name | string | null | 公告上的名称 |
market | string | twse(上市)或 tpex(上柜) |
kind | string | disposal 或 notice |
count | int | 交易所的累计次数(累计/累计次数) |
start, end | string | null | 处置期间,头尾两天都算;注意为 null |
condition | string | null | 处置:公告上的触发条件(連續三次、連續3個營業日、最近十個營業日已有六次 …)。注意:引用的款次(第一款、第五款);没有时为 null |
measure | string | null | 处置类型:第一次處置、第二次處置、再次處置、人工管制撮合、收足五成款券 …;注意与早期 TPEx 的列为 null |
match_minutes | int | null | 处置:从内文读出「约每N分钟撮合一次」的 N。内文没写时(约 2011 年以前的 TWSE 处置内文都是空白,以及不是撮合类的措施)与注意皆为 null |
reason | string | null | 公告全文;交易所没有公布内文时为 null(2011-03 以前的 TWSE 处置都没有)(处置为处置内容,注意为注意交易资讯) |
close, pe | float | null | 公告当时的收盘价与本益比;TWSE 处置一律为 null |
| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Invalid start date, expected YYYY-MM-DD"}(或 end) | start/end 格式错误 |
| 400 | {"error": "start must not be after end"} | 区间颠倒 |
| 400 | {"error": "Invalid date, expected YYYY-MM-DD"} | date 格式错误 |
| 400 | {"error": "use either date or start/end"} | date 与 start 或 end 同时送出 |
| 400 | {"error": "Invalid stock_id"} | 格式检查未通过 |
| 400 | {"error": "kind must be one of ['disposal', 'notice']"} / {"error": "market must be one of ['twse', 'tpex']"} | 不认得的值 |
| 400 | {"error": "start/end range is <n> days; max 366 (inclusive) without stock_id — split into smaller ranges"} | 不带 stock_id 时区间超过 366 天 |
| 503 | {"error": "Data temporarily unavailable. Please retry shortly."} | 要查的表目前无法提供(48 小时没更新,或读不到),稍后重试,绝不要当成「没有公告」。只检查这次要查的 kind/market 那几张表 |
date 是公告日,start 是生效第一天。要问「D 日是否处置中」,用 date=D(或 start=end=D),不要用公告日。start/end 是公告的期间;期间内遇到休市或暂停交易时,实际结束日会延后,这份数据没有记录。match_minutes 依当时的规则而定(TPEx 从 2026-08-10 起由 5/20 分钟改为 2 分钟),要逐列读,绝不要假设固定值。/studio/market/twstock/batch/<data_type> | 名称 | 说明 | 可用值 | 默认 |
|---|---|---|---|
data_typestring · path必填 | 数据集 | price, price_adj, per, institutional, shareholding, foreign_shareholding, financials, balance_sheet, monthly_revenue, ratios, dividend | |
stock_idsstring · query必填 | 代码 | 逗号分隔,≤ 50 | |
startstring · query | 起始日 | YYYY-MM-DD(只有 dividend 会严格验证) | 依 data_type 而定 |
endstring · query | 结束日 | YYYY-MM-DD | 依 data_type 而定 |
payload = requests.get(f"{BASE_URL}/studio/market/twstock/batch/per" , headers=headers, params={"stock_ids": "2330,6182", "start": "2026-08-04", "end": "2026-08-08"}, timeout=120).json()# {"data_type": "per",# "data": {"2330": [{"date": "2026-08-04", "dividend_yield": 0.95, "PER": 31.19, "PBR": 10.21, "stock_id": "2330"}, ...],# "6182": [...]},# "failed": []}{"data_type", "data": {"<stock_id>": [...rows...]}, "failed": [...]}。各列与对应的单股端点完全相同。
failed:服务器端抓取失败的代码(频率限制或上游错误),重试这些。data 与 failed 里都没有的代码,就是真的没有数据。| 状态码 | 回应内容 | 情况 |
|---|---|---|
| 400 | {"error": "Unsupported data_type '<x>'. Supported: [...]"} | data_type 不对 |
| 400 | {"error": "stock_ids parameter required"} | 缺少 |
| 400 | {"error": "stock_ids exceeds max 50 per request"} | 超过上限 |
| 400 | {"error": "Invalid stock_id in list"} | 有代码格式检查未通过 |
| 400 | {"error": "Invalid start date, expected YYYY-MM-DD"} | 限 dividend |
ratios(财务比率):每个代码的数据列就是 /ratios/<stock_id> 的宽格式季数据("data": {"2330": [{"date": "2026-06-30", "stock_id": "2330", "roe_q": 11.3934, ...}], "2317": [...]})。没有财报的代码(ETF)不会出现在 data 也不会出现在 failed(不回 404);比率数据库还没准备好时,所有代码都会放进 failed(不回 503)。dividend 与 /dividend/<stock_id> 不同:只读已存的数据(不更新);未知代码或没有股利纪录的股票会直接缺席(不回 404);上游配额问题会出现在 failed,而不是回 503。