← 返回博客列表

【Python 量化取数指南 #12】北交所与指数数据接口实测

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

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

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

1. 你将得到什么

  • 北交所 2 类端点(列表、历史 MA)+ 指数 2 类端点(列表、历史 K 线)的完整代码
  • 一个把「北交所股票 + 对应指数」拼起来看的小示例
  • 一个离线 run_check(),不填 token 也能验证逻辑

2. 本篇取数约定

  • 北交所列表:/bj/list/all
  • 北交所历史 MA:/bj/history/ma/{code}/d/n{code}=北交所代码如 920000.BJ
  • 指数列表:/hz/list/hszs
  • 指数历史 K 线:/hz/history/fsjy/{code}.{market}/{lvl}(如 000001.SH/d
  • 请求:GET https://api.zhituapi.com<path>?token=<你的智兔token>
  • 北交所代码后缀 .BJ,指数 .SH/.SZ,别混

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. 跑通示例:北交所 + 指数

def demo_bse_index():
    # 4.1 北交所列表 /bj/list/all
    data, err = _get("/bj/list/all")
    if err:
        print("北交所列表失败:", err)
    else:
        items = data if isinstance(data, list) else (data.get("data") or [])
        print(f"  北交所股票 {len(items)} 只")

    # 4.2 北交所历史 MA /bj/history/ma/920000.BJ/d/n
    data, err = _get("/bj/history/ma/920000.BJ/d/n")
    if err:
        print("北交所MA失败:", err)
    else:
        print("  北交所MA结构:", type(data).__name__)

    # 4.3 指数列表 /hz/list/hszs
    data, err = _get("/hz/list/hszs")
    if err:
        print("指数列表失败:", err)
    else:
        items = data if isinstance(data, list) else (data.get("data") or [])
        print(f"  指数 {len(items)} 个")

    # 4.4 指数历史 K 线 /hz/history/fsjy/000001.SH/d
    data, err = _get("/hz/history/fsjy/000001.SH/d")
    if err:
        print("指数K线失败:", err)
    else:
        bars = data if isinstance(data, list) else (data.get("data") or [])
        print(f"  上证日线 {len(bars)} 根")

def run_check():
    synth = [{"code": "920000.BJ", "name": "合成北交所股"}]
    print(f"  [run_check] 合成北交所 {len(synth)} 只: {synth[0]['name']}")

if __name__ == "__main__":
    demo_bse_index()
    run_check()

返回字段说明:北交所列表含 code/dm(如 920000.BJ)、name/mc;指数列表含 code/dm(如 000001.SH)、name/mc。历史 K 线/MA 每项含 date/rqclose/sp/收盘ma5/ma20 等。

5. 坑与注意事项

  1. 后缀别混:北交所 .BJ、上证 .SH、深证 .SZ,错后缀直接 404。
  2. 北交所流动性差异大:小票成交稀薄,回测滑点要额外考虑。
  3. 指数代码 vs 个股代码000001.SH 是指数(上证综指),600519.SH 是个股,别混。
  4. MA 端点参数/bj/history/ma/{code}/d/n 末段是级别+窗口,错格式返回空。
  5. 字段名三套close/sp/收盘,用 _hit_key
  6. 限流:北交所列表量大,批量加 sleep

6. 常见报错速查

报错 / 现象 原因 处理
404 后缀错(.BJ/.SH) 核对市场后缀
返回空 级别/窗口格式错 检查 d/n
指数当个股 代码混 区分 000001.SH vs 600519.SH
KeyError 字段名不符 print(data) 看真实 key

7. 小结与下一篇预告

小结:北交所走 /bj/list/all + /bj/history/ma/,指数走 /hz/list/hszs + /hz/history/fsjy/;核心是「后缀别混 + 指数/个股区分」。

下一篇计划写 #13《数据本地化:落库与读取实战》:把前面拉的行情落进本地库,回测时直接读,不再每次联网。

8. 免责声明

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


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

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