A股量化策略回测实战:从行情数据到绩效评估(第 13 篇):放量突破策略

A股量化策略回测实战:从行情数据到绩效评估(第 13 篇):放量突破策略

前言

第 12 篇的通道突破只看价格,但"无量空涨"常常是陷阱。真实突破通常伴随放量------资金真金白银进场。本篇在 Donchian 突破基础上加成交量确认:价格创 N 日新高、且成交量显著大于近 M 日均量,才判定有效突破。

一、接口原始字段梳理

1)hsstock/history 日线(取量价)

字段来自官网说明(零编造),本篇用 t, h, l, c, v:

字段 含义
t 交易日
h, l, c 高、低、收(突破判定)
v 成交量(放量确认)

路径:{BASE}/hsstock/history/{代码.市场}/{级别 d}/{除权 f}/{licence}?st=&et=&lt=。

二、自研衍生统计指标

  • N 日新高 c_t > max(h over 前N日)(同第 12 篇)。
  • 均量 vol_ma = mean(v over 前M日)。
  • 放量比 vr = v_t / vol_ma;vr > k(如 1.5)视为显著放量。
  • 有效突破 = 价格突破 且 vr > k。
  • 量比用"前 M 日"均值(不含当日),避免当日量自己抬高均值(前视)。

三、数据表设计

sql 复制代码
CREATE TABLE IF NOT EXISTS volbreak_signal (
    stock TEXT NOT NULL,
    t     TEXT NOT NULL,
    vr   REAL,    -- 量比
    sig  TEXT,    -- VALIDBREAK/HOLD
    PRIMARY KEY (stock, t)
);

四、完整代码

4.1 放量突破信号

python 复制代码
import sqlite3, json, time

BASE = "https://api.biyingapi.com"
LICENCE = "YOUR_LICENCE_HERE"
DB_PATH = "backtest.db"


def biying_api_get_retry(url, timeout=15, max_retry=3):
    import urllib.request
    last = None
    for i in range(max_retry):
        try:
            req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
            with urllib.request.urlopen(req, timeout=timeout) as r:
                return json.loads(r.read().decode('utf-8', 'ignore'))
        except Exception as e:
            last = e
            if i < max_retry - 1:
                time.sleep(1 + i)
    raise last


def fetch_daily(stock, start, end, adj='f', level='d', lt=1200):
    url = (f"{BASE}/hsstock/history/{stock}/{level}/{adj}/{LICENCE}"
           f"?st={start}&et={end}&lt={lt}")
    data = biying_api_get_retry(url)
    bars = data if isinstance(data, list) else data.get('data', [])
    return sorted(bars, key=lambda b: b['t'])


def vol_breakout(bars, n=20, m=20, k=1.5):
    """放量突破:价格新高 且 量比>k(纯计算)。"""
    out = []
    for i, b in enumerate(bars):
        if i < max(n, m):
            out.append(('HOLD', None)); continue
        window_h = bars[i - n:i]
        hh = max(float(x['h']) for x in window_h)
        vol_win = bars[i - m:i]
        vol_ma = sum(float(x['v']) for x in vol_win) / len(vol_win)
        c = float(b['c']); v = float(b['v'])
        vr = v / vol_ma if vol_ma > 0 else 0.0
        sig = 'VALIDBREAK' if (c > hh and vr > k) else 'HOLD'
        out.append((sig, round(vr, 3)))
    return out


def demo_vb():
    bars = [
        {'t': 'D1', 'h': 10.5, 'c': 10.0, 'v': 1e6},
        {'t': 'D2', 'h': 10.6, 'c': 10.2, 'v': 1.1e6},
        {'t': 'D3', 'h': 11.0, 'c': 10.9, 'v': 1.0e6},
        {'t': 'D4', 'h': 11.2, 'c': 11.3, 'v': 2.0e6},   # 新高+放量
    ]
    for b, s in zip(bars, vol_breakout(bars, 3, 3, 1.5)):
        print(b['t'], s)


if __name__ == '__main__':
    demo_vb()

五、关键业务说明

  • 放量是"确认"不是"必然" :放量突破成功率高,但高位巨量也可能是出货;量比阈值 k 要回测定。
  • 均量窗口 M 与突破窗口 N 可不同:M 看"近期活跃度"、N 看"区间高点",两者独立调参。
  • 复权影响量 :用前复权 f 时成交量已按股本调整,跨除权日的量比才可比(呼应第 2 篇)。
  • 仍可能过拟合:n/m/k 三个参数,第 29 篇统一排查。

六、拓展练习

  1. 把量比阈值 k 改成"动态分位"(如高于近 60 日量比 80 分位),自适应不同标的。
  2. 仅在"放量突破 + 第 6 篇多头排列"时买入,双重确认。
  3. 接引擎回测 000001.SZ,对比纯通道突破的回撤。
  4. 统计放量突破后 5/10/20 日平均收益,验证"量价齐升"惯性。

下篇预告

系列第 14 篇:涨停、跌停事件策略 ------ 量价之外,A 股特有的涨跌停事件 是强信号。下一篇用 hslt 真实的涨停/跌停股池,做"涨停股次日动量"与"跌停股超跌反弹"的事件策略。

免责申明 :本篇全部代码与回测结果仅作为量化编程与策略研究的学习演示,所有回测均为方法演示,不构成任何投资建议。市场有风险,投资需谨慎。

相关推荐
文丑颜不良啊1 小时前
LeetCode626~650题目解析
java·leetcode
cxyxixiy1 小时前
数智码力:数据核对不用人工比对,Python 快速完成多表格差异校验
开发语言·python·学习
LMT流氓兔1 小时前
第五单元——第11课:自动测试“拒绝后绝不能写入”
数据库·人工智能·python·langchain
tianbin9111 小时前
批处理与微调辅助场景:Claude 中转并发、链路缓存与压测对比
java·开发语言·缓存
ratel️2 小时前
小墨析 · Office Agent 日常办公不烧心
python·langchain·word·excel·fastapi·js·ppt
frjc2 小时前
Spring AI 里 ChatClient 和 ChatModel 有什么区别?什么时候该用哪个?
java·开发语言·spring·ai
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 圈子功能的表设计方案
java·开发语言·交友
文丑颜不良啊2 小时前
LeetCode601~625题目解析
java·leetcode
MrGet2 小时前
一步一步学Python(三):文件读写
python