☰
沪深港通数据实战:从北向资金到择时信号的全链路量化(第 1 篇):沪深港通全景接入:资金流向概览、历史走势与总览
2026/9/27 23:07:36 网站建设 项目流程

沪深港通数据实战:从北向资金到择时信号的全链路量化(第 1 篇):沪深港通全景接入:资金流向概览、历史走势与总览

一、前言

沪深港通是外资配置 A 股、内资配置港股的主通道。市场习惯把「北向资金」(沪股通+深股通)视为外资情绪的风向标,把「南向资金」(港股通沪+港股通深)视为内资南下意愿的晴雨表。

本季《沪深港通数据实战:从北向资金到择时信号的全链路量化》规划 12 篇,围绕官方/ht/nbzj/接口族,从资金流向概览一路做到可落地的北向择时信号。本篇是开篇,目标是把 5 个基础接口一次性接入、落库,并验证「北向≈沪股通+深股通」这一自研恒等式,为后续走势深度(第 2 篇)与择时综合指标(第 11 篇)打底。

系列沿用统一规范:域名固定api.biyingapi.com;LICENCE / DB_PATH / LOG_FILE为全局常量;网络请求统一走biying_api_get_retry带重试;本地落库用 SQLitequant.db;代码块语法均通过ast.parse自检。

二、接口与字段

本篇覆盖 5 个只读接口,字段全部以官方 API 文档为准(零编造)。

2.1 最新资金流向概览/ht/nbzj/lxgl

字段含义(按官方字段名推断)
type渠道类型(如沪股通/深股通/港股通等)
tname渠道名称
dir流向方向
netbuy净买入额
netin净流入额
remain当日余额
up / ping / down上涨 / 平盘 / 下跌家数
idx / idxdm / idxzd关联指数 / 指数代码 / 指数涨跌
status状态

2.2 北向资金历史走势/ht/nbzj/bxls/阶段(如1)

字段含义
bx北向资金净流入
hgt沪股通净流入
sgt深股通净流入
t日期

2.3 南向资金历史走势/ht/nbzj/nxls/阶段(如1)

字段含义
nx南向资金净流入
ggth港股通(沪)净流入
ggts港股通(深)净流入
t日期

2.4 北向资金历史总览/ht/nbzj/bxzl

字段含义
bx1m / hgt1m / sgt1m近 1 月北向 / 沪股通 / 深股通累计
bx6m / hgt6m / sgt6m近 6 月累计
bx1y / hgt1y / sgt1y近 1 年累计
bxall / hgtall / sgtall开通以来全部累计

2.5 南向资金历史总览/ht/nbzj/nxzl

字段含义
nx1m / ggth1m / ggts1m近 1 月南向 / 港股通沪 / 港股通深累计
nx6m / ggth6m / ggts6m近 6 月累计
nx1y / ggth1y / ggts1y近 1 年累计
nxall / ggthall / ggtsall开通以来全部累计

三、自研衍生指标

接口只返回裸字段,以下指标全部在 Python 中手写:

  1. 北向恒等式校验:bx ≈ hgt + sgt。官方分别给出北向与沪/深分项,我们用加法做交叉验证,偏差接近 0 说明数据自洽。
  2. 南向恒等式校验:nx ≈ ggth + ggts,同理。
  3. 概览涨跌广度:用up / ping / down计算北向通道覆盖标的的上涨占比,作为情绪快照。

四、数据表设计

5 张表,分别存放 5 个接口。以quant.db为统一库。

CREATETABLEht_lxgl(typeTEXT,tnameTEXT,dirTEXT,netbuyREAL,netinREAL,remainREAL,upINTEGER,pingINTEGER,downINTEGER,idxTEXT,idxdmTEXT,idxzdREAL,statusTEXT,tsTEXT);CREATETABLEht_bxls(tTEXT,bxREAL,hgtREAL,sgtREAL);CREATETABLEht_nxls(tTEXT,nxREAL,ggthREAL,ggtsREAL);CREATETABLEht_bxzl(bx1mREAL,hgt1mREAL,sgt1mREAL,bx6mREAL,hgt6mREAL,sgt6mREAL,bx1yREAL,hgt1yREAL,sgt1yREAL,bxallREAL,hgtallREAL,sgtallREAL,tsTEXT);CREATETABLEht_nxzl(nx1mREAL,ggth1mREAL,ggts1mREAL,nx6mREAL,ggth6mREAL,ggts6mREAL,nx1yREAL,ggth1yREAL,ggts1yREAL,nxallREAL,ggthallREAL,ggtsallREAL,tsTEXT);

五、完整代码

importurllib.request,json,sqlite3,time,loggingimportpandasaspdfromdatetimeimportdatetime LICENCE="YOUR_LICENCE_HERE"DB_PATH="quant.db"LOG_FILE="season4_article1.log"BASE="https://api.biyingapi.com"logging.basicConfig(filename=LOG_FILE,level=logging.INFO,format="%(asctime)s %(levelname)s %(message)s")defbiying_api_get_retry(url,timeout=15,max_retry=3):"""带重试的官方接口请求封装。"""last=Noneforiinrange(max_retry):try:req=urllib.request.Request(url,headers={"User-Agent":"Mozilla/5.0"})withurllib.request.urlopen(req,timeout=timeout)asresp:returnjson.loads(resp.read().decode("utf-8"))exceptExceptionase:last=e logging.warning("retry %d/%d %s %s",i+1,max_retry,url,e)time.sleep(1)logging.error("api failed %s %s",url,last)returnNonedefwith_exchange_suffix(code):"""沪深港通接口返回的代码已是标准代码(如 600519.SH / 00700.HK),原值透传。"""returncodedefget_conn():returnsqlite3.connect(DB_PATH)def_as_list(data):returndataifisinstance(data,list)else[data]defsave_lxgl():url=f"{BASE}/ht/nbzj/lxgl/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnrows=_as_list(data)conn=get_conn()conn.execute("""CREATE TABLE IF NOT EXISTS ht_lxgl ( type TEXT, tname TEXT, dir TEXT, netbuy REAL, netin REAL, remain REAL, up INTEGER, ping INTEGER, down INTEGER, idx TEXT, idxdm TEXT, idxzd REAL, status TEXT, ts TEXT)""")forrinrows:conn.execute("INSERT INTO ht_lxgl VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)",(r.get("type"),r.get("tname"),r.get("dir"),r.get("netbuy"),r.get("netin"),r.get("remain"),r.get("up"),r.get("ping"),r.get("down"),r.get("idx"),r.get("idxdm"),r.get("idxzd"),r.get("status"),datetime.now().isoformat()))conn.commit();conn.close()logging.info("lxgl saved %d rows",len(rows))defsave_bxls(stage=1):url=f"{BASE}/ht/nbzj/bxls/{stage}/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnrows=_as_list(data)conn=get_conn()conn.execute("CREATE TABLE IF NOT EXISTS ht_bxls (t TEXT, bx REAL, hgt REAL, sgt REAL)")forrinrows:conn.execute("INSERT INTO ht_bxls VALUES (?,?,?,?)",(r.get("t"),r.get("bx"),r.get("hgt"),r.get("sgt")))conn.commit();conn.close()logging.info("bxls saved %d rows",len(rows))defsave_nxls(stage=1):url=f"{BASE}/ht/nbzj/nxls/{stage}/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnrows=_as_list(data)conn=get_conn()conn.execute("CREATE TABLE IF NOT EXISTS ht_nxls (t TEXT, nx REAL, ggth REAL, ggts REAL)")forrinrows:conn.execute("INSERT INTO ht_nxls VALUES (?,?,?,?)",(r.get("t"),r.get("nx"),r.get("ggth"),r.get("ggts")))conn.commit();conn.close()logging.info("nxls saved %d rows",len(rows))defsave_bxzl():url=f"{BASE}/ht/nbzj/bxzl/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnconn=get_conn()conn.execute("""CREATE TABLE IF NOT EXISTS ht_bxzl ( bx1m REAL, hgt1m REAL, sgt1m REAL, bx6m REAL, hgt6m REAL, sgt6m REAL, bx1y REAL, hgt1y REAL, sgt1y REAL, bxall REAL, hgtall REAL, sgtall REAL, ts TEXT)""")conn.execute("INSERT INTO ht_bxzl VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",(data.get("bx1m"),data.get("hgt1m"),data.get("sgt1m"),data.get("bx6m"),data.get("hgt6m"),data.get("sgt6m"),data.get("bx1y"),data.get("hgt1y"),data.get("sgt1y"),data.get("bxall"),data.get("hgtall"),data.get("sgtall"),datetime.now().isoformat()))conn.commit();conn.close()logging.info("bxzl saved")defsave_nxzl():url=f"{BASE}/ht/nbzj/nxzl/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnconn=get_conn()conn.execute("""CREATE TABLE IF NOT EXISTS ht_nxzl ( nx1m REAL, ggth1m REAL, ggts1m REAL, nx6m REAL, ggth6m REAL, ggts6m REAL, nx1y REAL, ggth1y REAL, ggts1y REAL, nxall REAL, ggthall REAL, ggtsall REAL, ts TEXT)""")conn.execute("INSERT INTO ht_nxzl VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",(data.get("nx1m"),data.get("ggth1m"),data.get("ggts1m"),data.get("nx6m"),data.get("ggth6m"),data.get("ggts6m"),data.get("nx1y"),data.get("ggth1y"),data.get("ggts1y"),data.get("nxall"),data.get("ggthall"),data.get("ggtsall"),datetime.now().isoformat()))conn.commit();conn.close()logging.info("nxzl saved")defself_check():"""自研校验:北向=沪股通+深股通;南向=港股通沪+港股通深。"""conn=get_conn()df=pd.read_sql("SELECT * FROM ht_bxls ORDER BY t",conn)conn.close()if{"bx","hgt","sgt"}.issubset(df.columns):df["check"]=(df["hgt"]+df["sgt"]-df["bx"]).abs()print(df.tail(5).to_string())print("最大偏差:",df["check"].max())if__name__=="__main__":save_lxgl()save_bxls(stage=1)save_nxls(stage=1)save_bxzl()save_nxzl()self_check()

六、业务关键点

  • lxgl是「最新快照」,每次拉取建议覆盖写入或带时间戳追加;本篇用追加+时间戳,便于看日内变化。
  • bxls / nxls的阶段参数控制时间粒度(如 1=日度),不同会员等级返回窗口不同,落地前先用小阶段验证。
  • bxzl / nxzl是累计值单条记录,建表时注意去重(可按ts保留多版本)。
  • 所有代码走biying_api_get_retry,避免盘中限频导致整批失败。

七、拓展练习

  1. 把self_check的偏差阈值固化成断言,偏差超 1e-6 即告警。
  2. 用lxgl的up/ping/down计算每日北向覆盖标的上涨占比,存成独立时序表。
  3. 将 5 张表统一加上source字段标记接口名,方便后续联表。

八、下篇预告

下一篇《北向资金走势深度:累计净流入与自研动量信号》将基于本篇落库的ht_bxls / ht_bxzl,计算累计净流入曲线、净流入 N 日动量,并给出可量化的择时阈值信号。

免责申明:文中所有数据处理逻辑仅为编程演示,仅为数据演示,不构成投资建议。市场有风险,投资需谨慎。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询