← 返回博客列表

【零依赖量化数据实战 #26】港股通更多成交维度

2026年08月28日 11:12 · 智兔数服 · 零依赖量化数据实战

摘要:【零依赖量化数据实战 #26】港股通更多成交维度 系列:《零依赖量化数据实战》|零依赖 · 纯 GET · 不 import 任何 SDK 适用:想用 Python 把 港股通 (北向/南向、沪/深两条通道)的成

系列:《零依赖量化数据实战》|零依赖 · 纯 GET · 不 import 任何 SDK
适用:想用 Python 把港股通(北向/南向、沪/深两条通道)的成分股、十大成交股、资金历史走势、历史成交、个股持股排名一次拉齐的量化爱好者;数据由智兔数服提供,不依赖任何行情终端。

1. 你将得到什么

  • 13 个官方接口的最小可用封装,分五组:
  • 个股通成分股(2):/ht/nbzj/ggth(沪港股通成分)、/ht/nbzj/ggts(深港股通成分),按涨跌幅降序。
  • 十大成交股(4):/ht/nbzj/hgts(沪股通)、/ht/nbzj/sgts(深股通)、/ht/nbzj/hcjd(港股通沪)、/ht/nbzj/scjd(港股通深),近 30 个交易日、按日期倒序。
  • 资金历史走势(2):/ht/nbzj/bxls/{jd}(北向)、/ht/nbzj/nxls/{jd}(南向),{jd}=1/6/12/all
  • 历史成交(4):/ht/nbzj/hgls(沪股通)、/ht/nbzj/shls(深股通)、/ht/nbzj/ghls(港→沪)、/ht/nbzj/gsls(港→深),按日期倒序。
  • 个股持股排名(1):/ht/nbzj/sgpm/{zq}(深股通持股排名,季频快照)。
  • 两个对字段名不敏感的抽取函数:by_change_pct(按涨跌幅排序)、top_by_amount(按成交额取前 N)。

2. 端点语义表

GET https://api.zhituapi.com/ht/nbzj/ggth?token=你的智兔token        -> 沪港股通成分股(涨跌幅降序)
GET https://api.zhituapi.com/ht/nbzj/ggts?token=你的智兔token        -> 深港股通成分股(涨跌幅降序)

GET https://api.zhituapi.com/ht/nbzj/hgts?token=你的智兔token        -> 沪股通近30日十大成交股
GET https://api.zhituapi.com/ht/nbzj/sgts?token=你的智兔token        -> 深股通近30日十大成交股
GET https://api.zhituapi.com/ht/nbzj/hcjd?token=你的智兔token        -> 港股通(沪)近30日十大成交股
GET https://api.zhituapi.com/ht/nbzj/scjd?token=你的智兔token        -> 港股通(深)近30日十大成交股

GET https://api.zhituapi.com/ht/nbzj/bxls/all?token=你的智兔token     -> 北向资金历史走势(jd=1/6/12/all)
GET https://api.zhituapi.com/ht/nbzj/nxls/all?token=你的智兔token     -> 南向资金历史走势

GET https://api.zhituapi.com/ht/nbzj/hgls?token=你的智兔token         -> 沪股通历史成交
GET https://api.zhituapi.com/ht/nbzj/shls?token=你的智兔token         -> 深股通历史成交
GET https://api.zhituapi.com/ht/nbzj/ghls?token=你的智兔token         -> 港→沪 历史成交
GET https://api.zhituapi.com/ht/nbzj/gsls?token=你的智兔token         -> 港→深 历史成交

GET https://api.zhituapi.com/ht/nbzj/sgpm/all?token=你的智兔token     -> 深股通个股持股排名(季频快照)

鉴权:token 走查询参数;走势类 {jd} 为路径参数(1/6/12/all);持股排名 {zq} 为路径参数(默认 all)。数据来自 智兔数服(www.zhituapi.com)。

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

成分股「涨跌幅」可能叫 涨跌幅 / 涨跌幅(%) / zdf / change_pct;成交股「成交额」可能叫 成交额 / amount / 成交金额 / cje。统一候选键命中:

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:
        kl = k.lower()
        if kl in low:
            return d[low[kl]]
    return None

4. 核心模板函数

import sys, requests

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:
        kl = k.lower()
        if kl in low:
            return d[low[kl]]
    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 Exception 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 Exception:
        return None, f"非 JSON:{r.text.strip()[:140]}"

def fetch_component(kind):          # ggth / ggts
    return _get(f"/ht/nbzj/{kind}")

def fetch_top_traded(kind):         # hgts / sgts / hcjd / scjd
    return _get(f"/ht/nbzj/{kind}")

def fetch_flow_history(kind, jd="all"):  # bxls / nxls ; jd=1/6/12/all
    return _get(f"/ht/nbzj/{kind}/{jd}")

def fetch_deal_history(kind):       # hgls / shls / ghls / gsls
    return _get(f"/ht/nbzj/{kind}")

def fetch_hold_rank(zq="all"):      # sgpm/{zq}
    return _get(f"/ht/nbzj/sgpm/{zq}")

def by_change_pct(rows, descending=True):
    """成分股按涨跌幅候选键排序(中性,不写红绿)。"""
    if not isinstance(rows, list):
        return rows
    def sc(x):
        return _to_float(_hit_key(x, ["涨跌幅", "涨跌幅(%)", "zdf", "change_pct", "pct"])) or 0.0
    return sorted(rows, key=sc, reverse=descending)

def top_by_amount(rows, n=10):
    """十大成交股按成交额候选键取前 n。"""
    if not isinstance(rows, list):
        return rows
    def sc(x):
        return _to_float(_hit_key(x, ["成交额", "amount", "成交金额", "cje"])) or 0.0
    return sorted(rows, key=sc, reverse=True)[:n]

def selftest():
    # 合成数据仅逻辑自验,非真实行情
    comp = [
        {"name": "A", "涨跌幅": 3.1},
        {"name": "B", "zdf": -1.2},
        {"name": "C", "change_pct": 0.5},
    ]
    assert [x["name"] for x in by_change_pct(comp)] == ["A", "C", "B"]
    traded = [
        {"name": "X", "成交额": 100.0},
        {"name": "Y", "amount": 300.0},
        {"name": "Z", "cje": 200.0},
    ]
    assert [x["name"] for x in top_by_amount(traded, 2)] == ["Y", "Z"]
    for jd in ("1", "6", "12", "all"):
        assert jd in ("1", "6", "12", "all")
    print("selftest PASS")

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--selftest":
        selftest()
    else:
        for kind in ("ggth", "ggts"):
            print(f"{kind} ->", fetch_component(kind))
        for kind in ("hgts", "sgts", "hcjd", "scjd"):
            print(f"top.{kind} ->", fetch_top_traded(kind))
        for kind in ("bxls", "nxls"):
            print(f"flow.{kind} ->", fetch_flow_history(kind))
        for kind in ("hgls", "shls", "ghls", "gsls"):
            print(f"deal.{kind} ->", fetch_deal_history(kind))
        print("hold_rank ->", fetch_hold_rank("all"))

5. 代码自验结果

离线 selftest(合成数据,仅验证逻辑,不含任何真实行情):

selftest PASS

联网实测(占位 token,真实返回):

--- 联网实测(占位 token,预期 404 102:Licence证书不存在)---
ggth -> (None, '404 102:Licence证书(你的智兔token)不存在')
ggts -> (None, '404 102:Licence证书(你的智兔token)不存在')
top.hgts -> (None, '404 102:Licence证书(你的智兔token)不存在')
top.sgts -> (None, '404 102:Licence证书(你的智兔token)不存在')
top.hcjd -> (None, '404 102:Licence证书(你的智兔token)不存在')
top.scjd -> (None, '404 102:Licence证书(你的智兔token)不存在')
flow.bxls -> (None, '404 102:Licence证书(你的智兔token)不存在')
flow.nxls -> (None, '404 102:Licence证书(你的智兔token)不存在')
deal.hgls -> (None, '404 102:Licence证书(你的智兔token)不存在')
deal.shls -> (None, '404 102:Licence证书(你的智兔token)不存在')
deal.ghls -> (None, '404 102:Licence证书(你的智兔token)不存在')
deal.gsls -> (None, '404 102:Licence证书(你的智兔token)不存在')
hold_rank -> (None, '404 102:Licence证书(你的智兔token)不存在')

TOKEN = "你的智兔token" 换成你申请的真实 token,上述函数即可打印港股通成交维度数据。本文未编造任何真实数值。

6. 坑与注意事项

  1. 102 不代表路径对404 102 是「证书不存在」(鉴权先于路由),路径合法与否要靠客户端白名单自查。
  2. {jd} 取历史区间bxls/nxls{jd} 只接受 1/6/12/all,写别的会路由错误。
  3. sgpm 季频快照口径:上游 2026-08 起北向个股日频持股明细停更,本接口降级为季频持股快照(深股通),周期增持字段(zq*)多为 null,落盘建议带 _freq=quarterly
  4. 成分股沪/深可能一致:官方说明 2026-08 实测沪/深港股通成分列表可能完全一致,两接口仍分别提供,使用时以源站网页交叉核对。
  5. 涨跌幅中性处理:成分股按涨跌幅降序返回,代码里只排序不映射颜色(红绿因市场而异),避免写死涨跌色。

7. 小结与下篇预告

本篇把「港股通成分股 + 十大成交股 + 资金历史走势 + 历史成交 + 个股持股排名」拧成了 13 个零依赖接口的最小封装,重点解决了{jd} 区间参数sgpm 季频口径变更涨跌幅字段名中英文混用三个坑,配候选键排序即可一行出榜。

下一篇计划写 #27《沪深公司面:治理·分红·解禁与实时盘口》:讲解如何用官方接口拉取沪深公司的治理(高管/董事会/监事会)、分红/增发/解禁、季度利润与现金流,以及实时行情、五档盘口与涨跌停/集合竞价数据。

8. 免责声明

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


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

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

把代码里的 你的智兔token 换成你拿到的真实 token,上面的脚本就能直接打印港股通成交维度数据。

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