A股量化数据工程:从 REST 接口到策略信号(第 4 篇):行业与概念板块树构建

A股量化数据工程:从 REST 接口到策略信号(第 4 篇):行业与概念板块树构建

前言

做板块轮动、题材挖掘,第一件事是有一张「板块树」:指数、行业、概念之间谁挂在谁下面,代码怎么对应。接口 hszg/list 直接给出了完整的树形结构(带 type1/type2/level/pcode),本篇把它落库并还原成可遍历的层级,下一篇就能顺着树把成分股挂上去。

一、接口原始字段梳理

1)指数、行业、概念树

接口地址:https://api.biyingapi.com/hszg/list/{LICENCE}

字段 说明
name 节点名称(指数/行业/概念名)
code 节点代码
type1 一级类型(如 指数 / 行业 / 概念)
type2 二级类型(细分)
level 层级(0 根、1 一级、2 二级...)
pcode 父节点代码
pname 父节点名称
isleaf 是否叶子节点(1 是 / 0 否)

2)根据指数、行业、概念找相关股票

接口地址:https://api.biyingapi.com/hszg/gg/{指数、行业、概念代码}/{LICENCE}

字段 说明
dm 股票代码(带市场后缀)
mc 股票名称
jys 交易所

3)根据股票找相关指数、行业、概念

接口地址:https://api.biyingapi.com/hszg/zg/{股票代码}/{LICENCE}

字段 说明
code 关联节点代码
name 关联节点名称

二、自研衍生统计指标

  1. 层级深度 :由 level 还原每个节点到根的路径,便于「概念→行业→指数」上钻。
  2. 叶子计数 :isleaf=1 的节点即最细颗粒(通常是概念或个股集合),统计每个行业下挂几个概念。
  3. 反向映射 :用 hszg/zg 把「股票→板块」反向建索引,和正向树互为补充。

树结构与反向映射均基于原始 code/pcode 业务字段二次计算,接口不返回现成层级对象。

三、数据表设计

sql 复制代码
CREATE TABLE IF NOT EXISTS board_tree (
    code   TEXT PRIMARY KEY,
    name   TEXT,
    type1  TEXT,
    type2  TEXT,
    level  INTEGER,
    pcode  TEXT,
    pname  TEXT,
    isleaf INTEGER
);

CREATE TABLE IF NOT EXISTS board_stock_map (
    board_code TEXT,
    dm    TEXT,
    mc    TEXT,
    jys   TEXT,
    PRIMARY KEY (board_code, dm)
);

CREATE TABLE IF NOT EXISTS stock_board_map (
    dm    TEXT,
    code  TEXT,
    name  TEXT,
    PRIMARY KEY (dm, code)
);

四、完整代码

python 复制代码
import requests
import sqlite3
import time

LICENCE = "YOUR_LICENCE"
BASE = "https://api.biyingapi.com"
DB_PATH = "quant.db"

def biying_api_get_retry(url, timeout=15, max_retry=3):
    for i in range(max_retry):
        try:
            r = requests.get(url, timeout=timeout)
            r.raise_for_status()
            return r.json()
        except Exception as e:
            if i == max_retry - 1:
                raise
            time.sleep(1 + i)

def fetch_board_tree():
    data = biying_api_get_retry(f"{BASE}/hszg/list/{LICENCE}")
    return data.get("data", []) if isinstance(data, dict) else []

def fetch_stocks_of_board(bcode):
    data = biying_api_get_retry(f"{BASE}/hszg/gg/{bcode}/{LICENCE}")
    return data.get("data", []) if isinstance(data, dict) else []

def fetch_boards_of_stock(dm):
    data = biying_api_get_retry(f"{BASE}/hszg/zg/{dm}/{LICENCE}")
    return data.get("data", []) if isinstance(data, dict) else []

def save_tree(rows):
    con = sqlite3.connect(DB_PATH)
    con.executemany(
        "INSERT OR REPLACE INTO board_tree"
        "(code,name,type1,type2,level,pcode,pname,isleaf)"
        "VALUES(?,?,?,?,?,?,?,?)",
        [[r.get("code"), r.get("name"), r.get("type1"), r.get("type2"),
          r.get("level"), r.get("pcode"), r.get("pname"), r.get("isleaf")]
         for r in rows])
    con.commit(); con.close()

def build_path(rows):
    """自研:由 pcode 还原每个节点的祖先链。"""
    by_code = {r.get("code"): r for r in rows}
    def ancestors(code, acc=None):
        acc = acc or []
        node = by_code.get(code)
        if not node or not node.get("pcode"):
            return acc
        p = by_code.get(node["pcode"])
        if p:
            acc.insert(0, p.get("name"))
            return ancestors(p["code"], acc)
        return acc
    return {r.get("code"): ancestors(r.get("code")) for r in rows}

if __name__ == "__main__":
    tree = fetch_board_tree()
    save_tree(tree)
    paths = build_path(tree)
    leaves = [r for r in tree if r.get("isleaf") == 1]
    print(f"板块节点共 {len(tree)} 个,叶子(最细) {len(leaves)} 个")
    # 演示:取一个概念节点,看它的祖先链与成分股
    sample = leaves[0] if leaves else {}
    bcode = sample.get("code")
    if bcode:
        print(f"示例节点 {sample.get('name')} 祖先链:", " > ".join(paths.get(bcode, [])))
        stocks = fetch_stocks_of_board(bcode)
        print(f"  成分股示例:", stocks[:3])

五、关键业务说明

  • pcode 是树的根 :所有层级关系靠 pcode 外键自指,落库后用 build_path 自研还原路径,无需接口给对象。
  • 叶子即最细颗粒 :isleaf=1 通常对应概念或个股集合,是做成分股映射的最小单元。
  • 正反向两张表 :board_stock_map 正向(板块→股)、stock_board_map 反向(股→板块),查询时双向命中。

六、拓展练习

  1. 统计每个一级行业(type1=行业)下挂多少个概念叶子,做一个「行业---概念」宽度榜。
  2. 用 stock_board_map 找出同时属于「新能源车」与「锂电池」两个概念的股票。
  3. 把 build_path 输出成 JSON 树,供前端板块选择器直接渲染。

下篇预告

A股量化数据工程:从 REST 接口到策略信号(第 5 篇):板块成分股映射与对齐

下一篇把 hszg/gg 的成分股批量落进 board_stock_map,并演示如何把板块涨跌与成分股行情做对齐,得到「板块强弱 = 成分股中位数涨跌幅」。
免责申明 :本篇全部代码、接口调用仅作为量化编程学习演示,仅为数据演示,不构成投资建议。市场有风险,投资需谨慎。

相关推荐
弹简特1 小时前
【Java项目-企悦抽】17-抽奖模块02-抽奖接口实现
java·开发语言·状态模式·springboot
2601_962780911 小时前
需求预测校招能力栈|2026 届 JD 梳理、日常任务、面试题与备考方案
python·数据挖掘·数据分析
吴声子夜歌1 小时前
Nginx应用与运维——Nginx编译及部署(部署)
java·运维·nginx
乌暮1 小时前
JVM 原理与实践:从运行时数据区到线上故障排查
java·开发语言·jvm·后端·学习·面试
miofly1 小时前
GitHub 今日推荐|lipflow:无麦克风唇读文字输入工具
python·开源·github
code2cat1 小时前
【随笔】MCP缓存期限与共享范围:让Agent复用资料时记住边界
java·后端·缓存·ai agent·mcp
架构师那点事儿1 小时前
将 HuggingFace 自己的英译中模型迁移到 ONNX
人工智能·python·深度学习
维克兜率天2 小时前
【维克】配对交易的季节性:哪些品种适合长拿?
android·开发语言·笔记·python·算法·kotlin·量化