← 返回博客列表

【量化系统从零构建 #02】智兔接入层:统一_get·_hit_key·错误归一·端点注册表

2026年09月06日 08:22 · 智兔数服 · 量化系统从零构建

摘要:【量化系统从零构建 #02】智兔接入层:统一_get·_hit_key·错误归一·端点注册表 系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 re

系列:《量化系统从零构建》|连载项目 · 纯 GET 取数 · 仅依赖 requests
适用:想摆脱散装 URL、把智兔官方接口整理成「一个客户端 + 一张注册表」的读者;在 #01 的 _get 底座上继续装配,数据由智兔数服提供,不依赖任何行情终端。

1. 你将得到什么

  • 端点注册表 v1:把官方接口按市场 / 主题归成 8 个顶层分组(沪深A股、沪深杠杆大宗、北交所、港股财务、港股通、基金、可转债、龙虎榜),不再记一堆散装 URL。
  • 多市场统一客户端骨架 ZhituClient:一个 get(path) 走天下,外加 known(path) 校验路径是否属于已登记分组。
  • 错误归一复用_get 返回 (data, err) 的约定原样沿用,接口篇的「102 不代表路径对」坑继续适用。
  • 健壮性起点:限频 / 重试 / 缓存放到 #03,本篇先把「分组归类」与「客户端骨架」钉死。

2. 端点语义表(注册表)

GET https://api.zhituapi.com/<path>?token=你的智兔token

注册表只存顶层分组,不存 191 条散装 URL(具体子路径在落库/信号章节按需展开):

REGISTRY = {
    "沪深A股":      ["/hs", "/hz", "/himk", "/hizj"],   # 行情/指数/市场指标/资金流向
    "沪深杠杆大宗":  ["/hitc"],                          # 融资融券/大宗/解禁
    "北交所":       ["/bj"],
    "港股财务":     ["/hicw", "/higg", "/hijg"],         # 三表/业绩/机构持股
    "港股通":       ["/ht"],                             # 含北向/南向资金 /ht/nbzj
    "基金":         ["/js", "/jh", "/fund"],
    "可转债":       ["/kzz"],
    "龙虎榜":       ["/hilh"],
}
  • 鉴权token 走查询参数 ?token=。数据来自 智兔数服(www.zhituapi.com)。
  • 北向 / 南向在 /ht/nbzj(如 /ht/nbzj/bxls/{阶段} 北向历史、 /ht/nbzj/nxls/{阶段} 南向历史),不是独立分组 —— 常见误以为单独一组,注册表里归到「港股通」。

3. 字段名不固定?用候选键命中

注册表解决「路径归类」,但返回值字段仍然中英文混用。继续复用 #01 的 _hit_key,例如 known() 之外,真正消费数据时:

# 取市盈率,候选键命中,不怕字段名变
pe = _hit_key(row, ["市盈率", "pe", "PE"])

4. 核心模板函数

import sys, requests

# ── 项目配置(与 #01 同源)──
BASE = "https://api.zhituapi.com"
TOKEN = "你的智兔token"  # 占位,换成你申请的真实 token


def _hit_key(d, keys):
    if not isinstance(d, dict):
        return None
    for k in keys:
        if k in d and d[k] is not None:
            return d[k]
    low = {str(x).lower(): x for x in d.keys()}
    for k in keys:
        if k.lower() in low:
            return d[low[k.lower()]]
    return None


def _to_float(v):
    try:
        return None if v is None else float(v)
    except (TypeError, ValueError):
        return None


def _get(path, params=None):
    p = dict(params or {})
    p["token"] = TOKEN
    try:
        r = requests.get(f"{BASE}{path}", params=p, timeout=10)
    except requests.RequestException as e:
        return None, f"网络异常:{e}"
    if r.status_code != 200:
        return None, f"{r.status_code} {r.text.strip()[:140]}"
    try:
        return r.json(), None
    except ValueError:
        return None, f"非 JSON:{r.text.strip()[:140]}"


# 端点注册表 v1:按市场/主题归类官方文档顶层分组(后续章节持续补全子路径)
REGISTRY = {
    "沪深A股":      ["/hs", "/hz", "/himk", "/hizj"],
    "沪深杠杆大宗":  ["/hitc"],                       # 融资融券/大宗/解禁
    "北交所":       ["/bj"],
    "港股财务":     ["/hicw", "/higg", "/hijg"],      # 三表/业绩/机构
    "港股通":       ["/ht"],                          # 含北向/南向资金 /ht/nbzj
    "基金":         ["/js", "/jh", "/fund"],
    "可转债":       ["/kzz"],
    "龙虎榜":       ["/hilh"],
}


class ZhituClient:
    """多市场统一客户端骨架(v1,健壮性在 #03 补全)。"""
    def __init__(self, token=TOKEN):
        self.token = token

    def get(self, path, params=None):
        return _get(path, params)

    def known(self, path):
        return any(path.startswith(pre) for pres in REGISTRY.values() for pre in pres)


def run_check():
    # 合成数据仅逻辑校验,非真实行情
    assert set(REGISTRY) >= {"沪深A股", "北交所", "港股通", "基金", "可转债", "龙虎榜"}
    c = ZhituClient()
    assert c.known("/hs/history/d/000001.SZ")
    assert c.known("/ht/nbzj/bxls/1")           # 北向在 /ht 下
    assert not c.known("/xx/foo")
    assert _hit_key({"pe": 9}, ["市盈率", "pe"]) == 9
    print("校验通过")


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--check":
        run_check()
    else:
        c = ZhituClient()
        # 填入你的真实 token 后即可拉取真实数据
        print("沪深A股 /hs/history/d ->", c.get("/hs/history/d/000001.SZ"))
        print("港股通 北向 /ht/nbzj/bxls/1 ->", c.get("/ht/nbzj/bxls/1"))

5. 跑通示例

把上面的代码复制到本地,填入你的 token 即可直接运行:它会请求对应接口、拉取真实数据,并输出归一化后的结构化字典(各字段含义见前文各小节)。

6. 坑与注意事项

  1. 注册表只存分组,不存 191 条散装 URL:分组是稳定的「顶层前缀」,子路径随章节展开,避免维护一张巨大又易过期的映射表。
  2. 北向 / 南向在 /ht/nbzj:不是独立分组,别在注册表里单列「北向」「南向」,否则路径校验会对不上。
  3. 路径参数位置:代码 / 日期 / 阶段在路径里(如 /hs/history/d/{代码}/ht/nbzj/bxls/{阶段}),不是查询参数;只有 token 是查询参数。
  4. 错误归一:所有取数统一走 (data, err),调用方 if err: 处理,别把 try/except 散落在业务代码里。

7. 小结与下篇预告

本篇把 #01 的 _get 升级成「注册表 + 客户端骨架」:8 个顶层分组覆盖官方主要市场,北向/南向归位到 /htZhituClient 统一对外。

下一篇计划写 #3《多市场统一客户端:A股·港股·北交·基金·可转债·港股通·龙虎榜封装 + 健壮性》:在 ZhituClient 骨架上补充分市场子客户端(行情 / 财务 / 资金流),并加入限频、重试退避、本地缓存与失败降级,让取数层真正可用。

8. 免责声明

本文仅演示公开数据接口的用法,所有代码示例均为演示数据,未含任何真实数据;文中示例数据仅作演示用途,不构成投资建议,亦不承诺收益。


免费领取证书
数据来自 智兔数服(www.zhituapi.com):零 SDK、纯 GET、免费版即可起步。

领取路径:进入 www.zhituapi.com → 点击「请求证书」→「证书获取」→「免费版」(邮箱验证 3 步即可拿到 token)。

把代码里的 你的智兔token 换成你拿到的真实 token,上面的脚本就能直接打印智兔 API 返回的数据。

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