沪深港通数据实战:从北向资金到择时信号的全链路量化(第 3 篇):沪、深股通成分股行情:字段解析与清洗
一、前言
北向资金的「态度」既体现在整体净流入(第 1、2 篇),也体现在它在哪些标的上进出。本篇接入沪股通成分股行情ht/nbzj/hgtc与深股通成分股行情ht/nbzj/sgtc,把北向标的池的实时行情落库,并自研「北向成分股当日平均涨跌幅」作为情绪代理变量,为第 8 篇的个股周期排名、第 11 篇的综合择时做数据铺垫。
二、接口与字段
2.1 沪股通成分股行情/ht/nbzj/hgtc
| 字段 | 含义(按官方字段名推断) |
|---|---|
| dm / mc | 代码 / 名称 |
| fm | 今开 |
| h / l / o / yc | 最高 / 最低 / 开盘 / 昨收 |
| p / ud / pc | 最新价 / 涨跌额 / 涨跌幅 |
| hs / lb / v / cje | 换手 / 量比 / 成交量 / 成交额 |
| lt / sz / sjl | 流通市值 / 总市值 / 实流通 |
| pe | 市盈率 |
| zf / zs | 振幅 / 涨速 |
| zdf60 / zdfnc | 60 日涨跌幅 / 年初至今涨跌幅 |
| t | 时间 |
2.2 深股通成分股行情/ht/nbzj/sgtc
字段与hgtc完全一致(23 个)。
三、自研衍生指标
- 北向成分股当日平均涨跌幅:
pc.mean(),衡量北向标的整体强弱。 - 涨停家数 / 跌停家数:
pc >= 9.9与pc <= -9.9的计数。 - PE 中位数:北向池估值水位参考。
四、数据表设计
两张结构相同的表,列名与官方字段一一对应,统一以 TEXT 存储原始值,读取时再pd.to_numeric。
CREATETABLEht_hgtc(dmTEXT,mcTEXT,fmTEXT,hTEXT,hsTEXT,lbTEXT,lTEXT,ltTEXT,oTEXT,peTEXT,pcTEXT,pTEXT,szTEXT,cjeTEXT,udTEXT,vTEXT,ycTEXT,zfTEXT,zsTEXT,sjlTEXT,zdf60TEXT,zdfncTEXT,tTEXT);-- ht_sgtc 同构五、完整代码
importurllib.request,json,sqlite3,time,loggingimportpandasaspdfromdatetimeimportdatetime LICENCE="YOUR_LICENCE_HERE"DB_PATH="quant.db"LOG_FILE="season4_article3.log"BASE="https://api.biyingapi.com"logging.basicConfig(filename=LOG_FILE,level=logging.INFO,format="%(asctime)s %(levelname)s %(message)s")HGT_COLS=["dm","mc","fm","h","hs","lb","l","lt","o","pe","pc","p","sz","cje","ud","v","yc","zf","zs","sjl","zdf60","zdfnc","t"]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)returnNonedef_as_list(data):returndataifisinstance(data,list)else[data]defsave_board(name,path):url=f"{BASE}/ht/nbzj/{path}/{LICENCE}"data=biying_api_get_retry(url)ifnotdata:returnrows=_as_list(data)conn=sqlite3.connect(DB_PATH)coldef=",".join(f"{c}TEXT"forcinHGT_COLS)conn.execute(f"CREATE TABLE IF NOT EXISTS{name}({coldef})")ph=",".join("?"*len(HGT_COLS))forrinrows:conn.execute(f"INSERT INTO{name}VALUES ({ph})",[r.get(c)forcinHGT_COLS])conn.commit();conn.close()logging.info("%s saved %d rows",name,len(rows))defsave_hgtc():save_board("ht_hgtc","hgtc")defsave_sgtc():save_board("ht_sgtc","sgtc")defboard_sentiment():"""自研:北向成分股情绪快照。"""conn=sqlite3.connect(DB_PATH)fornamein["ht_hgtc","ht_sgtc"]:df=pd.read_sql(f"SELECT dm, mc, pc, pe FROM{name}",conn)ifdf.empty:continuedf["pc"]=pd.to_numeric(df["pc"],errors="coerce")df["pe"]=pd.to_numeric(df["pe"],errors="coerce")print(f"[{name}] 平均涨跌幅={df['pc'].mean():.3f}"f"涨停={(df['pc']>=9.9).sum()}跌停={(df['pc']<=-9.9).sum()}"f"PE中位数={df['pe'].median():.2f}")conn.close()if__name__=="__main__":save_hgtc()save_sgtc()board_sentiment()六、业务关键点
- 两接口返回的是成分股列表快照,盘中多次拉取可捕捉北向标的强弱变化;落库建议带时间戳或覆盖写。
- 字段
pc是涨跌幅(百分比),pe可能缺失或为负(亏损股),pd.to_numeric(errors="coerce")是必须的。 - 北向成分股池与全市场行情结构几乎一致,本篇单独落库便于后面按「北向标签」做分组统计。
七、拓展练习
- 把
ht_hgtc与ht_sgtc合并成一张带market字段的宽表,方便统一分析。 - 用
zdf60(60 日涨跌幅)找出近 60 日北向强势股,与第 8 篇排名做交叉。 - 将涨停家数做成日内时序,观察北向标的情绪拐点。
八、下篇预告
下一篇《港股通成分股行情:沪、深港股通接入》将接入ht/nbzj/ggth与ht/nbzj/ggts,补齐南向(港股通)标的池行情,并把 A/H 联动分析所需的港股数据接进来。
免责申明:文中所有数据处理逻辑仅为编程演示,仅为数据演示,不构成投资建议。市场有风险,投资需谨慎。