综合

A股日内策略数据缺口:集合竞价K线拼法,同花顺/通达信/TickDB对比,量比第一根Bar就错了

作者: TickDB Research · 发布: 2026/9/16 · 阅读: 8

标签: 知乎A001

如果你用Python拉过A股1分钟K线、算过量比因子、跑过开盘段策略——下面这个坑,我大概率不是唯一踩过的人。

拉K线、算量比、跑回测、曲线好看、上实盘、信号失灵。我最近又走了一遍这个循环。一开始怀疑策略逻辑,改了几版参数,回测还是好看,实盘还是失灵。后来换了个方向查——不查策略,查数据。问题出在9:30那根K线上。

你的量比因子,可能从第一根K线就已经算错了——而你的回测结果,恰好证明了它“有效”。

30秒抓住重点

>

谁会遇到:用Python拉1分钟K线、算量比、做开盘段策略的人

什么时候会遇到:回测信号稳定,实盘对不上;或者换了个数据源,策略行为突然变了

问题在哪:9:30那根K线的成交量里,可能混了集合竞价的量,也可能没混——取决于你的数据源怎么拼

怎么判断:拉一次09:29到09:32的K线,看9:30 Bar的四个价格是否一样,成交量是不是明显比9:31小

能带走什么:一张判断表 + 3行验证代码,下次接数据源时直接跑

本文回答三个问题:

  1. 9:30 Bar的成交量里到底装了什么?
  2. 怎么判断我现在的数据源属于哪种拼法?
  3. 如果拼法不对,有什么替代方案?

9:30那根Bar,不是普通的1分钟

我以前也把9:30和9:31当成相邻的两根普通K线。后来做集合竞价的时候才发现,它们之间隔着一整套撮合机制。

9:25,交易所主机把集合竞价的所有申报汇集到一起,按一个价格统一撮合,产生开盘价。9:30,连续竞价才开始。集合竞价是“所有人报完价,选一个成交量最大的价格统一成交”,连续竞价是“一笔订单冲进来,找到对手方就成交”。这两套机制产生的成交量,性质完全不同。

但K线数据里,这个分界线可能被抹掉了。问题出在数据源对集合竞价量的处理方式上。

拼法集合竞价量放哪9:30 Bar成交量量比分母干不干净
通达信模式塞进9:30 Bar包含竞价量(偏大)不干净
同花顺模式单独放9:25 Bar只有连续竞价量干净
TickDB单独放9:30 Bar只有集合竞价量干净

这张表的正确读法:量比分母是否干净,取决于9:30 Bar的成交量里有没有混入集合竞价量。混入了,分母偏大,量比数值系统性偏低。

同花顺和通达信的处理方式来自行业公开讨论,不是本次实测结论。TickDB的处理方式来自本次实测。

两种拼法没有对错。但如果你回测用一套、实盘用另一套,量比的分子分母口径就不一致。回测时看起来稳定的信号,实盘可能完全反过来。

回测里看不出来的问题

我一开始没意识到这个问题,因为回测里根本看不出来。

从头到尾用同一套数据源、同一套拼法,回测曲线永远好看。只有换数据源、或者上实盘用另一套行情时,它才会突然暴露。

有统计证据表明量比是有意义的因子。海通证券的一份研报显示,量比的Rank IC为0.01,t值为2.87(来源:海通证券研报)。这个数字不大,但有统计意义。正因为量比本身信号微弱,K线拼法错误对它的污染才更致命——微弱信号被偏差一冲,方向可能直接反转。

回测结果与实盘不一致的常见数据原因有哪些?

复权口径不一致、交易日历不对齐、K线拼法不同——前两个经常被讨论,第三个很少被检查。

怎么判断你的数据属于哪种拼法

判断方法不复杂。取一个正常交易日,拉09:29到09:32的1分钟K线,看9:30那根Bar。

我用TickDB的K线接口跑了一遍。接口参数是实测确认过的:symbol(单数)、interval=1mstart_time/end_time用毫秒时间戳。注意,这个接口的bars参数不生效,要用limit

import requests

url = "https://api.tickdb.ai/v1/market/kline"
headers = {"X-API-Key": "YOUR_API_KEY"}
params = {
    "symbol": "000001.SZ",
    "interval": "1m",
    "start_time": 1789349280000,  # 2026-09-14 09:28:00
    "end_time": 1789349580000,    # 2026-09-14 09:33:00
    "limit": 20
}

resp = requests.get(url, headers=headers, params=params)
klines = resp.json()["data"]["klines"]

for bar in klines[:4]:
    print(bar["time"], bar["open"], bar["high"], bar["low"], bar["close"], bar["volume"])

这段代码验证的是:9:30那根Bar的四个价格是否一样,成交量是否明显小于9:31。跑出来的输出:

09:30:00  open=11.73  high=11.73  low=11.73  close=11.73  volume=2341
09:31:00  open=11.74  high=11.81  low=11.72  close=11.80  volume=30249

9:30那根Bar的四个价格完全一样:开盘=最高=最低=收盘=11.73。成交量是2341,只有9:31那根(30249)的7.74%。

如果你的9:30 Bar也满足这两个条件——四个价格一样,成交量明显比9:31小——说明你的数据源把集合竞价量单独放了。 量比分母是干净的。

如果价格有波动,或者成交量跟9:31差不多,说明集合竞价量可能混在里面了。需要手动拆,或者换一个独立Bar的数据源。

分时数据用于日内策略时需要注意哪些陷阱?

第一个陷阱就是:9:30 Bar不是连续的起点,它可能是一个混合体。

我踩过的两个坑

第一个坑:以为side字段能帮我判断。 我原本想用逐笔成交里的side字段来区分——集合竞价没有主动方,side应该是neutral;连续竞价应该有buy/sell。但实测发现,连续竞价的样本里也会出现neutral。所以不能只靠side判断。集合竞价的逐笔side需要你在9:15-9:25自己验证,我这次没抓到那个窗口的样本。

第二个坑:以为9:31一定不等于9:30。 不要用“开盘价≠收盘价”来判断它是不是连续竞价Bar。我看了另一天的数据,9:31那根虽然有波动,但开盘和收盘恰好相等。判断集合竞价Bar的可靠特征是四个价格一样,不是9:31一定不等于。

还有一个实测发现:这个接口的bars参数不生效。 我一开始用bars=390想拉全天数据,返回的还是默认100条。必须用limit才能控制数量。这是文档里没写、但实际调用会遇到的坑。

下一步你可以做什么

如果你正在做开盘段量能策略,下一个交易日可以用你现在的数据源拉一次09:29到09:32的1分钟K线,看9:30那根Bar的四个价格是否一样,看它的成交量是否明显比9:31小。两个条件都不满足的话,量比分母可能已经被污染了。

如果跑完发现9:30 Bar的成交量不对劲,TickDB的独立Bar设计是一个可以直接对照的样本——它的9:30 Bar是集合竞价专属,9:31起才是连续竞价第一根。同样的验证代码,换成它的接口跑一遍,两组数字放在一起看,拼法差异就很清楚了。

你的量比因子,可能从第一根K线就已经算错了——而你的回测结果,恰好证明了它“有效”。

集合竞价量确认后,下一个问题是:竞价量占全天成交量的比例,是否是一个独立的预测因子?这是CAP系列下一篇的主题。


参考资料与文献

  1. 海通证券研报:量比因子Rank IC=0.01,t=2.87,分组日收益呈现单调性
  2. TickDB K线接口实测记录:2026-09-14,000001.SZ,09:30 Bar open=high=low=close=11.73,volume=2341;09:31 Bar open=11.74,close=11.80,volume=30249
  3. 同花顺与通达信K线聚合模式差异:行业公开讨论与用户实践记录

通过 TickDB API 获取实时行情数据

一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。

免费领取 API Key查看 API 文档

相关文章