A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
前言
量在价先。成交骤增、连续放量往往对应资金进场;成交骤减、连续缩量对应观望或出货尾声。接口 himk/cjzz(骤增)、cjzj(骤减)、lxfl(连续放量)、lxsl(连续缩量)给出四类量能异动,本篇自研量能温度计,区分「放量上涨」与「放量下跌」。
一、接口原始字段梳理
1)成交骤增 / 骤减个股
接口地址:https://api.biyingapi.com/himk/cjzz/{LICENCE}(骤增)、https://api.biyingapi.com/himk/cjzj/{LICENCE}(骤减)
| 字段 | 说明 |
|---|---|
| t | 日期 |
| dm | 股票代码 |
| mc | 股票名称 |
| c | 现价 |
| zdf | 涨跌幅 |
| iscq | 是否创新高(接口原始标记) |
| v | 成交量 |
| pv | 原始成交总量 |
| zjl | 资金流(接口原始字段) |
| zjf | 资金(接口原始字段) |
2)连续放量 / 缩量个股
接口地址:https://api.biyingapi.com/himk/lxfl/{LICENCE}(连续放量)、https://api.biyingapi.com/himk/lxsl/{LICENCE}(连续缩量)
| 字段 | 说明 |
|---|---|
| t | 日期 |
| dm | 股票代码 |
| mc | 股票名称 |
| c | 现价 |
| zdf | 涨跌幅 |
| iscq | 是否创新高 |
| v | 成交量 |
| pv | 原始成交总量 |
| flday | 连续放量天数 |
| pzdf | 平均涨跌幅 |
| ispcq | 是否盘中 |
| phs | 平均换手率 |
二、自研衍生统计指标
- 放量进攻度 :骤增股中
zdf > 0的占比,越高资金越偏进攻。 - 连续放量强度 :按
flday排序,天数越长量能趋势越明确。 - 量价背离 :连续放量但
pzdf < 0= 放量滞涨,标记风险。
占比与排序基于原始
zdf/flday字段自研。
三、数据表设计
sql
CREATE TABLE IF NOT EXISTS scan_vol_burst (
dm TEXT, t TEXT, c REAL, zdf REAL, v REAL, pv REAL, zjl REAL, zjf REAL,
kind TEXT, -- zz(骤增)/zj(骤减)
PRIMARY KEY (dm, t, kind)
);
CREATE TABLE IF NOT EXISTS scan_vol_cont (
dm TEXT, t TEXT, c REAL, zdf REAL, v REAL, flday INTEGER,
pzdf REAL, phs REAL, kind TEXT, -- fl(连续放量)/sl(连续缩量)
PRIMARY KEY (dm, t, kind)
);
CREATE TABLE IF NOT EXISTS scan_vol_temp (
t TEXT PRIMARY KEY,
attack_ratio REAL,
top_flday INTEGER
);
四、完整代码
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(path):
d = biying_api_get_retry(f"{BASE}/himk/{path}/{LICENCE}")
return d.get("data", []) if isinstance(d, dict) else []
def attack_ratio(rows):
if not rows:
return 0.0
up = sum(1 for r in rows if (r.get("zdf") or 0) > 0)
return round(up / len(rows), 3)
if __name__ == "__main__":
zz = fetch("cjzz"); zj = fetch("cjzj")
fl = fetch("lxfl"); sl = fetch("lxsl")
con = sqlite3.connect(DB_PATH)
for r in zz + zj:
kind = "zz" if r in zz else "zj"
con.execute(
"INSERT OR REPLACE INTO scan_vol_burst(dm,t,c,zdf,v,pv,zjl,zjf,kind)"
"VALUES(?,?,?,?,?,?,?,?,?)",
[r.get("dm"), r.get("t"), r.get("c"), r.get("zdf"), r.get("v"),
r.get("pv"), r.get("zjl"), r.get("zjf"), kind])
for r in fl + sl:
kind = "fl" if r in fl else "sl"
con.execute(
"INSERT OR REPLACE INTO scan_vol_cont(dm,t,c,zdf,v,flday,pzdf,phs,kind)"
"VALUES(?,?,?,?,?,?,?,?,?)",
[r.get("dm"), r.get("t"), r.get("c"), r.get("zdf"), r.get("v"),
r.get("flday"), r.get("pzdf"), r.get("phs"), kind])
t = zz[0].get("t") if zz else ""
ar = attack_ratio(zz)
top_fl = max([(r.get("flday") or 0) for r in fl], default=0)
con.execute(
"INSERT OR REPLACE INTO scan_vol_temp(t,attack_ratio,top_flday) VALUES(?,?,?)",
(t, ar, top_fl))
con.commit(); con.close()
print(f"日期 {t} 骤增股 {len(zz)} 只(放量进攻度{ar}) 连续放量最长{top_fl}天")
五、关键业务说明
- 放量要看方向 :骤增本身中性,
zdf > 0占比才区分进攻 / 出货。 - 连续天数 > 单次 :
flday连续放量比单日骤增更具趋势意义,优先看长周期。 - 背离标记 :连续放量 + 均价跌(
pzdf<0)= 量价背离,单独成池观察。
六、拓展练习
- 把
scan_vol_temp按日落库,看「放量进攻度」与第 17 篇牛熊宽度的相关性。 - 对
flday >= 5的连续放量股,叠加第 5 篇板块映射看是否主线共振。 - 用
lxsl(连续缩量)找「地量见底」候选(仅统计演示)。
下篇预告
A股量化数据工程:从 REST 接口到策略信号(第 19 篇):连续上涨与下跌排列
下一篇用
himk/lxsz与himk/lxxd拉取连续上涨 / 下跌个股,自研「连涨广度」与市场惯性指标。
免责申明 :本篇全部代码、接口调用仅作为量化编程学习演示,仅为数据演示,不构成投资建议。市场有风险,投资需谨慎。