集合竞价数据自动挖掘量化因子思路

用户头像mx_****60317
2026-11-06 发布

集合竞价怎么做量化因子?拆解开盘前的价格、成交量与买卖力量

开盘前几分钟,竞价金额暴增、价格快速上冲,看起来像强势,9:30 却可能低开回落。问题不在数据不够,而在信号没有被拆成可验证的因子。把竞价过程留痕,再把价格、量能、稳定性和市场位置组合起来,才有机会从“看盘经验”走向可回测研究。

竞价数据不是涨跌答案,而是一张开盘前的订单地图

集合竞价反映的是某个时间窗口内,买卖双方对开盘价格的集中报价。它能提供预期变化,却不能直接等同于真实成交,更不能把一笔大单理解成确定性资金流入。

竞价因子的价值,不是预测每只股票,而是让一批股票在同一时刻具备可比较的特征。

研究时要把三个概念分开:

概念 研究含义 常见误区
竞价价格 市场对开盘价的阶段性预期 把高开预期当成必然高开
竞价数量 报价活跃度与潜在撮合规模 把委托量当成已成交量
竞价变化 预期在 9:15 至 9:25 的重新定价 只看最后一条,不看过程

数据接口怎么分工

XTick 文档中与集合竞价研究相关的入口,可以按“实时观察、细节留存、历史回测、横截面辅助”来组织。实际路由、鉴权字段和返回字段,以当前文档为准。

研究任务 接口方向 用途
观察实时竞价过程 bidtime 记录竞价阶段的时间序列变化
查看单只股票竞价细节 biddetail 获取价格、数量、涨跌幅等明细字段
拉取历史竞价数据 bidhistory 形成跨交易日样本,避免只做盘中观察
叠加大盘环境 dayupdate 判断当天是普涨、普跌还是结构性行情
叠加板块环境 bk、gainian 做行业、概念和板块内相对排名

如果使用 Python SDK,建议把接口调用封装成统一的数据层,不要让策略代码直接依赖某个字段名。这样字段变更、分页规则或返回格式调整时,只需要改适配层。

一套能落地的竞价因子拆解

1. 价格预期因子

最基础的特征是竞价价格相对前收盘的偏离:

auction_gap = auction_price / prev_close - 1

它回答的是“市场预期以什么幅度开盘”。但单独使用很容易追高,实际研究中可以把它做成分位数、截面排名,或与近 20 日波动率进行标准化。

gap_zscore = auction_gap / rolling_std_20

同样的 2% 高开,放在低波动股票和高波动股票上,含义并不一样。

2. 竞价活跃度因子

竞价金额不能脱离股票自身流动性。更稳妥的做法是与历史成交额比较:

amount_ratio = auction_amount / mean(amount_20)

也可以用竞价金额除以流通市值,形成跨股票更容易比较的强度指标。这里要特别处理新股、停牌复牌股、长期低流动性股票,否则极端比值会制造大量伪信号。

3. 买卖失衡因子

如果接口提供买卖委托数量或买卖盘深度,可以构造:

imbalance = (buy_qty - sell_qty) / (buy_qty + sell_qty + 1e-8)

如果接口只有竞价成交数量,没有完整的买卖委托字段,就不要强行命名为“资金流入”。可以把它定义为“竞价成交强度”,并在文章、代码和回测报告中保持口径一致。

4. 竞价路径因子

只截取 9:25 最后一条数据,会丢掉一部分信息。更有区分度的特征,往往来自价格路径:

路径特征 计算思路 解释
竞价斜率 价格对时间做线性拟合 预期是持续抬升还是突然拉升
竞价波动 路径价格标准差 / 均值 报价是否稳定
重估幅度 price_925 - price_920 9:20 后预期如何变化
量价同步 价格变化与数量变化的相关性 价格上行是否伴随活跃度提升

持续抬升和最后一分钟突然冲高,表面涨幅相同,交易含义可能完全不同。

XTick 的实时数据适合在采集阶段保存多时间点快照,再在离线研究中计算路径特征。不要只保存最终值,否则后续无法重建竞价过程。

5. 相对位置因子

集合竞价信号很容易受到市场风格影响。单只股票高开 1%,可能是强势,也可能只是当天全市场都高开。建议加入:

  • 股票竞价涨幅减去市场竞价中位数;
  • 股票竞价强度减去所属行业中位数;
  • 个股竞价量能排名与板块竞价量能排名的差值;
  • 高开股票占比、涨停预期股票占比等市场广度指标。

相对因子通常比绝对值更适合横截面选股,因为它减少了指数涨跌和市场情绪对结果的干扰。

从接口到因子的最小研究流程

XTick 实时采集
        ↓
按交易日、股票、时间戳保存快照
        ↓
统一价格、数量、复权与停牌口径
        ↓
构造价格、量能、路径、失衡、相对位置因子
        ↓
按 9:25 截面排序,生成候选组合
        ↓
以 9:30 后可成交价格进行回测
        ↓
加入滑点、手续费、涨跌停和容量约束

下面是一段适配层示例。它故意不把接口地址和鉴权参数写死,实际使用时按 XTick 文档中的当前定义替换;研究代码只接收标准化后的 DataFrame。

from __future__ import annotations

import requests
import pandas as pd


def fetch_xtick_data(api_url: str, token: str, trade_date: str) -> pd.DataFrame:
    response = requests.get(
        api_url,
        params={"token": token, "date": trade_date},
        timeout=10,
    )
    response.raise_for_status()
    payload = response.json()

    rows = payload.get("data", payload)
    frame = pd.DataFrame(rows)
    frame["timestamp"] = pd.to_datetime(frame["timestamp"])
    frame["auction_gap"] = frame["auction_price"] / frame["prev_close"] - 1
    frame["amount_ratio"] = frame["auction_amount"] / frame["amount20_mean"]
    return frame


def build_cross_section(frame: pd.DataFrame) -> pd.DataFrame:
    result = frame.copy()
    result["gap_rank"] = result["auction_gap"].rank(pct=True)
    result["amount_rank"] = result["amount_ratio"].rank(pct=True)
    result["stability_rank"] = result["auction_stability"].rank(pct=True)
    result["score"] = (
        0.4 * result["gap_rank"]
        + 0.35 * result["amount_rank"]
        + 0.25 * result["stability_rank"]
    )
    return result.sort_values("score", ascending=False)

真实项目中,payload 的字段映射、异常状态和分页逻辑应放在适配层。策略层只使用统一字段,避免把“接口格式”误当成“因子逻辑”。

回测最容易踩的五个坑

时间穿越

9:25 形成的信号,不能使用 9:30 之后才知道的开盘价、开盘成交量或首分钟涨跌。开盘价可以作为执行结果,也可以作为标签,但不能同时作为 9:25 的输入特征。

把委托当成交

竞价期间的委托可能撤单、改价,也可能没有完全撮合。字段含义必须记录清楚,委托量、匹配量、成交量不能混用。

忽略交易制度

涨跌停、停牌复牌、风险警示、上市首日、除权除息和不同市场的撮合规则,都会影响竞价价格和可成交性。回测过滤条件应单独写出来,不要藏在一行复杂代码里。

只测一个市场阶段

竞价因子常常在强趋势、情绪高涨时表现突出,在震荡或快速下跌阶段失效。至少要做滚动窗口、牛熊分层和行业分层,观察收益是否依赖某一段行情。

忽略容量和成本

小市值股票的回测收益,可能经不起滑点和冲击成本。报告中应同时展示毛收益、净收益、换手率、最大回撤、收益波动、分组收益和成交容量。

一个更稳妥的组合方式

不要把单一因子阈值直接写成“高开就买”。可以把信号拆成三层:

层级 作用 示例
方向层 判断预期方向 auction_gap、相对市场涨幅
质量层 判断信号是否稳定 路径波动、量价同步、竞价持续性
风险层 判断是否值得执行 流动性、涨跌停距离、行业拥挤度

只有方向、质量和风险同时通过,才进入候选池。这样做的好处是,因子失效时可以定位到底是预期错了、信号不稳定,还是交易成本吞掉了收益。

知识点图文海报:集合竞价因子挖掘四句话

数据层:保存 9:15—9:25 的竞价快照,不只保存最后一条。

因子层:价格看偏离,数量看强度,路径看持续,相对位置看环境。

研究层:9:25 截面生成信号,9:30 之后按可成交价格回测。

风控层:委托不等于成交,竞价强不等于开盘后继续强。

┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│ XTick 竞价流  │ → │ 清洗与留痕    │ → │ 因子计算      │
│ bidtime       │   │ 时间/字段/状态 │   │ 价格/量能/路径 │
└──────────────┘   └──────────────┘   └──────┬───────┘
                                               ↓
┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│ 交易执行      │ ← │ 回测验证      │ ← │ 截面排序      │
│ 滑点/容量/风控 │   │ 分层/成本/稳定 │   │ 9:25 冻结信号 │
└──────────────┘   └──────────────┘   └──────────────┘

写在最后:把“盘感”翻译成数据结构

集合竞价最值得挖的,不是某个神奇阈值,而是预期如何形成、如何变化、是否得到量能支持,以及它在市场横截面中的相对位置。

能被保存的盘口,才有机会变成能被检验的因子;能被检验的因子,才值得进入实盘候选池。

发布或接入前,请以 XTick 当前接口文档、交易所规则和实际返回样例为准,特别核对时间戳、字段含义、数据权限、复权口径与历史数据完整性。

资料索引

评论