概览
找到能返回 ETF 当前报价、历史 K 线或两者兼有的免费接口,并快速验证响应。
通常是受限免费层:延迟行情、交易所范围、调用配额或个人用途许可都可能有限制。
覆盖范围、时间戳、复权规则、行情延迟、频率限制、再分发许可与错误处理。
QVeris 可帮助 Agent 发现并检查相关金融数据能力,再决定是否调用。
免费 ETF 行情 API:报价与历史 K 线数据
ETF 报价 API 通常返回最新成交价或收盘价、涨跌、币种、成交量和时间戳;ETF K 线数据 API 按周期返回开高低收与成交量。不要默认“实时”一定无延迟,免费层可能只提供延迟行情或有限市场。
应用必须先明确需要哪一种市场观测。最新成交可能已经陈旧,中间价依赖有效买卖报价,官方收盘遵循交易所规则,K 线则在明确时段与周期内汇总成交。盘前、常规盘和盘后数据不能在缺少时段标签与可比成交量口径时直接混合。
ETF 当前报价字段
核对价格、昨收、可用时的买卖价、成交量、交易所、币种、市场状态和明确的数据时间戳。
ETF 历史行情 API 字段
用于图表或回测时,要确认周期、历史深度、分红与拆分调整规则、时区以及缺失交易日的处理方式。
实时、延迟还是日终
记录每个市场的官方延迟说明。HTTP 响应很快,并不等于底层行情就是实时数据。
证券代码与交易所身份
同一代码可能出现在不同市场;接口支持时,应同时保存稳定标识符和交易所代码。
成交与报价条件
保存最新成交时间、买卖价与数量、报价时间、条件代码、市场状态和停牌状态。乱序、更正、竞价或零股成交未必代表当前可执行市场。
原始、复权与总回报历史
把原始 OHLCV 与拆分复权、分派复权和总回报序列分开,并说明是否再投资分派、成交量如何调整,以及公司行动何时生效。
基金与上市身份
区分法律基金、份额类别、交易所上市、交易币种和代码历史。多地上市可能代表同一策略,但价格、时段、汇率敞口、流动性和数据权利不同。
如何比较免费 ETF 行情数据 API
| 要求 | 检查内容 | 为什么重要 | 风险信号 |
|---|---|---|---|
| 覆盖范围 | ETF 标的范围、交易所、币种、退市代码。 | 决定目标代码能否稳定解析。 | 只写“全球”却没有市场清单。 |
| 时效 | 实时权限、延迟、更新频率、时间戳。 | 避免把过期行情显示为实时。 | 没有数据源时间戳。 |
| 配额 | 分钟/每日额度、单次代码成本、429 行为。 | 决定轮询和缓存方案是否可行。 | 宣称“不限量”却无政策说明。 |
| 许可 | 个人/商用、展示、存储、再分发许可。 | API 可调用不代表行情可再分发。 | 没有书面使用条款。 |
| 交易时段 | 盘前、常规盘、盘后、竞价与休市日。 | 决定基准价、K 线与所示时效。 | 所有成交混在无标签时间线中。 |
| 条件代码 | 成交与报价条件、更正、停牌和顺序。 | 区分有效市场状态与异常成交。 | 无法识别陈旧或更正数据。 |
| 复权 | 拆分、分派、原始与复权字段、版本。 | 避免虚假收益与历史断点。 | 只有一条无口径说明的收盘序列。 |
Python 获取 ETF 行情:安全接入步骤
展示报价前,先把供应商响应映射为下面使用的字段。校验器以数据源时间戳而不是 HTTP 到达速度判断时效;只有买卖价没有倒挂且报价足够新时,才返回中间价。
from datetime import datetime, timezone
from decimal import Decimal, InvalidOperation
def parse_time(value: str) -> datetime:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
if parsed.tzinfo is None:
raise ValueError("source timestamp must include a timezone")
return parsed
def validate_etf_quote(quote: dict, max_age_seconds: int = 60) -> dict:
required = {
"instrument_id", "symbol", "exchange", "currency",
"session", "market_status", "source_timestamp", "bid", "ask"
}
missing = required - quote.keys()
if missing:
raise ValueError(f"missing quote fields: {sorted(missing)}")
try:
bid = Decimal(str(quote["bid"]))
ask = Decimal(str(quote["ask"]))
last = None if quote.get("last") is None else Decimal(str(quote["last"]))
except InvalidOperation as exc:
raise ValueError("quote contains a non-numeric price") from exc
if bid <= 0 or ask <= 0 or (last is not None and last <= 0):
raise ValueError("prices must be positive")
if bid > ask:
raise ValueError("crossed market: bid is above ask")
source_time = parse_time(quote["source_timestamp"])
now = datetime.now(timezone.utc)
age_seconds = (now - source_time.astimezone(timezone.utc)).total_seconds()
if age_seconds < 0:
raise ValueError("source timestamp is in the future")
is_live_session = quote["market_status"] == "open"
is_stale = is_live_session and age_seconds > max_age_seconds
return {
"instrument_id": quote["instrument_id"],
"midpoint": (bid + ask) / Decimal("2"),
"last_trade": last,
"spread": ask - bid,
"source_time": source_time,
"age_seconds": age_seconds,
"is_stale": is_stale,
"session": quote["session"],
}
不能静默替换数值。若报价陈旧或买卖倒挂,应返回相应状态,并把最新成交单独保存。验证失败后若直接用 last 代替买卖报价,却不改变字段标签,就会把异常包装成看似合理但具有误导性的“当前价格”。
1. 确认 ETF 代码与交易所
先解析具体标的,保存交易所、币种和供应商标识符,不要只依赖展示代码。
2. 分别请求报价与 K 线
使用供应商文档里的 Python 或 HTTP 示例,从单个代码开始,先检查原始 JSON 再设计映射。
3. 验证时间戳与数值字段
按时区解析时间戳,拒绝缺失价格,区分空值与零,并分别保存原始收盘价与复权收盘价。
4. 添加缓存、退避与来源记录
遵守配额,遇到 429 时退避,按数据更新频率缓存,并保留供应商与抓取时间。
5. 在事件日重建 K 线与收益
测试分派、拆分、代码变更、转板、停牌、竞价和半日交易,用原始与复权数据重算收益,并确认盘中 K 线使用目标时段和时区。
6. 监控报价质量与连续性
标记买卖倒挂或锁定、陈旧时间戳、不可能的 OHLC 关系、重复 K 线、缺失交易日、负成交量,以及无法由公司行动解释的断点,并保留条件代码供排查。
7. 保存时点证据
保留原始响应、供应商时间、接收时间、行情权限、时段、上市 ID、条件代码、复权版本和抓取代码;历史修订不能无声覆盖早期研究实际使用的数值。
用 QVeris 发现 ETF 报价 API 能力
QVeris 是能力路由层,不是 ETF 交易所,也不承诺提供免费的实时行情权限。它可以帮助 Agent 搜索相关金融数据能力、检查输入输出,并遵循目标工具的公开条款进行调用。
- 在 QVeris 服务商详情中查找报价与历史行情能力。
- 调用前检查标识、市场、时段、报价或 K 线类型、时间戳、条件代码、复权规则、响应结构和公开限制。
- 在工具请求中明确上市、币种、数据类型、周期、时段、时效容忍度和原始或复权选择。
- 参考 QVeris 文档接入选定能力,并保留来源证据与安全失败状态。
免费 ETF 行情 API 常见问题
有免费的 ETF 行情 API 吗?
有些服务提供免费报价或历史行情额度,但通常限制市场、延迟、调用频率或用途,接入前应阅读公开条款。
如何用 API 获取 ETF 实时价格?
先确认代码与市场,再调用报价端点并检查行情时间戳。不要仅凭响应速度判断数据是否实时。
ETF 历史行情 API 返回哪些字段?
常见字段包括时间、开盘、最高、最低、收盘、成交量,也可能包含复权收盘价;具体结构以供应商文档为准。
免费 ETF API 有哪些限制?
常见限制包括延迟行情、少量调用、有限交易所、较短历史、禁止商用展示或再分发。
ETF 最新成交就是当前价格吗?
它只是最近一笔已报告交易,可能已经陈旧或带有特殊条件。判断当前可执行价格时,还要同时检查买卖价与数量、报价时间、交易时段和停牌状态。
ETF 历史价格是否应该做分派复权?
取决于用途。市场重建应保留原始价格,绩效分析可另存口径明确的复权或总回报序列,不能在没有标签的情况下互相替换。
为什么两个 ETF 行情 API 的收盘价不同?
交易市场、官方或最新成交收盘、时段、时间戳、更正状态、行情汇总规则或复权版本都可能不同,应先比较上市标识与原始事件记录。
