← 返回博客列表

【Python 量化取数指南 #11】ETF 数据接口实测与组合取数

2026年09月22日 11:15 · 智兔数服 · Python 量化取数指南

摘要:【Python 量化取数指南 #11】ETF 数据接口实测与组合取数 系列:《Python 量化取数指南》|连载项目 · 纯 GET 取数 · 仅依赖 requests 数据:由智兔数服提供。更多接口见 智兔数服

系列:《Python 量化取数指南》|连载项目 · 纯 GET 取数 · 仅依赖 requests
数据:由智兔数服提供。更多接口见 智兔数服技术博客

1. 你将得到什么

  • ETF 2 类端点的完整代码:ETF 实时列表、LOF 列表
  • 一个把「宽基/行业/主题」按名称过滤的小示例
  • 一个离线 run_check(),不填 token 也能验证逻辑

2. 本篇取数约定

  • ETF 实时列表:/jh/hq/etflist
  • LOF 列表:/jh/hq/loflist
  • 指数代码列表(配 ETF 跟踪标的):/hz/list/hszs
  • 请求:GET https://api.zhituapi.com<path>?token=<你的智兔token>
  • 返回多为 list;盘中才有实时价,休市为收盘快照

3. 核心模板(全系列复用)

import time, json, requests

BASE = "https://api.zhituapi.com"
TOKEN = "你的智兔token"      # 演示证书(免费版)即可起步

def _get(path, params=None, timeout=15, retry=3, backoff=1.5):
    params = dict(params or {})
    params["token"] = TOKEN
    url = BASE + path
    last = None
    for i in range(retry):
        try:
            r = requests.get(url, params=params, timeout=timeout)
            if r.status_code != 200:
                last = f"HTTP {r.status_code} {r.text[:120]}"
                time.sleep(backoff * (i + 1)); continue
            try:
                return r.json(), None
            except ValueError:
                last = f"非JSON响应: {r.text[:120]}"
                return None, last
        except requests.RequestException as e:
            last = str(e); time.sleep(backoff * (i + 1))
    return None, last

def _hit_key(d, *keys, default=None):
    if not isinstance(d, dict):
        return default
    for k in keys:
        if k in d and d[k] not in (None, "", []):
            return d[k]
    return default

def _to_float(x, default=float("nan")):
    try:
        return float(x)
    except (TypeError, ValueError):
        return default

4. 跑通示例:拉 ETF + 按关键词过滤

def demo_etf(keyword="沪深300"):
    data, err = _get("/jh/hq/etflist")
    if err:
        print("ETF列表失败:", err); return
    items = data if isinstance(data, list) else (data.get("data") or [])
    print(f"  ETF总数 {len(items)},含「{keyword}」的:")
    n = 0
    for it in (items or []):
        name = _hit_key(it, "name", "mc", "基金简称")
        if name and keyword in str(name):
            code = _hit_key(it, "code", "dm")
            price = _to_float(_hit_key(it, "price", "zxj", "收盘价", "nav"))
            print(f"    {code} {name} 价 {price}")
            n += 1
            if n >= 5:
                break

def run_check():
    synth = [{"code": "510300.SH", "name": "沪深300ETF", "price": 3.9}]
    hit = [x for x in synth if "沪深300" in x["name"]]
    print(f"  [run_check] 合成命中 {len(hit)} 条: {hit[0]['name']}")

if __name__ == "__main__":
    demo_etf("沪深300")
    run_check()

返回字段说明:ETF list 每项含 code/dm(代码)、name/mc(简称)、price/zxj/nav(价/净值)、amount/cje(成交额)等。字段名三套并存,统一 _hit_key

5. 坑与注意事项

  1. ETF vs LOF/jh/hq/etflist 是 ETF,/jh/hq/loflist 是 LOF,别混。
  2. 价 vs 净值:实时给「价」,盘后给「净值/IOPV」,字段可能不同,先 print 核对。
  3. 成交额看流动性:选 ETF 重点看 amount/cje,太小流动性差。
  4. 跟踪标的:ETF 跟踪某指数,指数代码走 /hz/list/hszs(第 2 篇)。
  5. 休市为快照:非交易时段价是上一交易日,别当实时。
  6. 字段名三套price/zxj/收盘价,用 _hit_key

6. 常见报错速查

报错 / 现象 原因 处理
429 轮询太频 降频 + 缓存
返回空 无数据 换交易日
价/净值不符 字段混 print(data) 看真实 key
KeyError 字段名不符 print(data) 看真实 key

7. 小结与下一篇预告

小结:ETF 用 /jh/hq/etflist、LOF 用 /jh/hq/loflist,核心是按 name 过滤宽基/行业 + 看 amount 判流动性;跟踪标的查 /hz/list/hszs

下一篇计划写 #12《北交所与指数数据接口实测》:用北交所与指数端点,补齐小众市场的取数。

8. 免责声明

本文仅演示公开数据接口的用法,所有代码示例均为演示数据,不构成任何投资建议;实际返回字段以接口文档与你的证书权限为准。数据由 智兔数服 提供,更多接口示例见 技术博客


免费领取证书 / 查看完整接口文档,可前往 智兔数服官网

想亲自试一下?免费获取证书