首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >分钟级行情数据入库规范:统一结束时刻标签、09:30集合竞价归并、周期合成与源数据逐根一致、根数/总量/价格校验,以及存不复权加除权因子的复权方案。

分钟级行情数据入库规范:统一结束时刻标签、09:30集合竞价归并、周期合成与源数据逐根一致、根数/总量/价格校验,以及存不复权加除权因子的复权方案。

原创
作者头像
用户12657240
发布于 2026-11-01 17:29:38
发布于 2026-11-01 17:29:38
950
举报

分钟 K 线是日内策略和高频因子研究的基础数据,但它的「坑」比日线多得多:时间标签有开始时刻和结束时刻两种约定,开盘集合竞价要不要单独成一根,自行合成的大周期和数据源提供的是否一致,跨除权日如何保证价格连续。本文以一个交易日的真实数据为样本,给出分钟级行情数据的入库规范与校验方案。示例使用 Python、pandas 与 QuantDash 的 Python SDK,标的 600519.SH,交易日 2026-10-30,于 2026-11-01 实跑。

一、目标与约束

维度

要求

周期

1m 为基础,5m/15m/30m/60m 可直接取或合成

标签

全库统一「结束时刻」约定

一致性

合成周期与源数据逐根一致

完整性

分钟成交量加总等于日线成交量

复权

存档不复权,研究按需复权

二、数据流

代码语言:plaintext
复制
 ┌──────────┐   ┌────────────┐   ┌──────────────┐   ┌────────────┐
 │ 分钟取数  │──▶│ 标签规范化  │──▶│ 集合竞价归并  │──▶│ 周期合成    │
 │ 1m/5m    │   │ 结束时刻    │   │ 09:30 并入    │   │ resample   │
 └──────────┘   └────────────┘   └──────────────┘   └─────┬──────┘
                                                          │
                                  ┌────────────┐   ┌──────▼─────┐
                                  │ 入库        │◀──│ 一致性校验  │
                                  │ 不复权存档  │   │ 量/价/根数  │
                                  └────────────┘   └────────────┘

三、时间标签约定

取同一交易日的 1m、5m、30m 三个周期:

代码语言:python
复制
from datetime import datetime
import pandas as pd
from quantdash import QuantDash

qd = QuantDash()  # 凭证从环境变量 QUANTDASH_API_KEY 读取

def ms(s):
    return int(datetime.strptime(s, "%Y-%m-%d %H:%M").timestamp() * 1000)

def get_min(symbol, period, day, adjust="none"):
    return qd.klines.get(symbol, period=period, adjust=adjust,
                         start_time=ms(f"{day} 09:00"), end_time=ms(f"{day} 15:10"),
                         count=10000, to_dataframe=True)

for p in ["1m", "5m", "30m"]:
    d = get_min("600519.SH", p, "2026-10-30")
    print(p, len(d), d["trade_time"].iloc[0], d["trade_time"].iloc[-1])

实跑结果整理如下:

周期

全天根数

第一根

上午末根

下午首根

末根

1m

241

09:30

11:30

13:01

15:00

5m

48

09:35

11:30

13:05

15:00

30m

8

10:00

11:30

13:30

15:00

结论:标签表示该 K 线的结束时刻。1m 的 241 根由 1 根 09:30 集合竞价、上午 120 根、下午 120 根组成。09:30 这一根开高低收均为 1363.00、成交量 1534。

入库规范第一条:全库只允许一种标签约定。若接入的其他数据源使用开始时刻,在规范化层统一加上一个周期长度后再入库。

四、集合竞价归并与周期合成

直接对 1m 按 5 分钟右闭重采样,得到 49 根,比源数据多 1 根,原因是 09:30 被单独分桶。源数据中第一根 5m 的成交量为 4148,恰好等于 09:30 的 1534 加 09:31–09:35 的 2614,说明集合竞价被并入第一根。

合成规则:

代码语言:python
复制
def resample_min(m1, rule="5min"):
    d = m1.copy()
    d["ts"] = pd.to_datetime(d["trade_time"])
    d.loc[d["ts"].dt.strftime("%H:%M") == "09:30", "ts"] += pd.Timedelta(minutes=1)
    agg = {"open": "first", "high": "max", "low": "min",
           "close": "last", "volume": "sum", "amount": "sum"}
    return (d.set_index("ts")
              .resample(rule, label="right", closed="right")
              .agg(agg).dropna(subset=["close"]))

m1 = get_min("600519.SH", "1m", "2026-10-30")
m5 = get_min("600519.SH", "5m", "2026-10-30")
mine = resample_min(m1)
print(len(mine), len(m5), int(mine["volume"].iloc[0]), int(m5["volume"].iloc[0]))

输出 48 48 4148 4148。午休时段没有数据,重采样后的空桶被 dropna 去除,无需额外处理。

合成方式

根数

第一根成交量

是否与源一致

直接右闭重采样

49

1534(单独一根)

否

09:30 归并后重采样

48

4148

是

五、一致性校验

入库前执行三项校验:

代码语言:python
复制
day = qd.klines.get("600519.SH", period="1d", adjust="none", count=3, to_dataframe=True)
day_vol = int(day.loc[day["trade_date"] == "2026-10-30", "volume"].iloc[0])
checks = {
    "bars_1m": len(m1) == 241,
    "bars_5m": len(m5) == 48,
    "vol_sum": int(m1["volume"].sum()) == int(m5["volume"].sum()) == day_vol,
}
print(checks, day_vol)

实跑三项均为 True,全天成交量 59927。

校验项

规则

失败处理

根数

1m=241、5m=48(全天交易日)

半日市或停牌单独标记

总量

分钟成交量加总 = 日线成交量

重拉当日

价格

分钟最高价的最大值 = 日线最高价

进入人工复核

标签

首根标签符合约定

拒绝入库

六、分钟级复权一致性

分钟数据同样受除权影响。以 2026-06-26 除权为例,取除权前 2026-06-24 的 5m 数据:

代码语言:python
复制
raw = get_min("600519.SH", "5m", "2026-06-24", adjust="none")
fwd = get_min("600519.SH", "5m", "2026-06-24", adjust="forward")
f = qd.klines.ex_factors("600519.SH", to_dataframe=True)
print(raw["close"].iloc[-1], round(fwd["close"].iloc[-1], 2),
      round(raw["close"].iloc[-1] / fwd["close"].iloc[-1], 6), f["ex_factor"].iloc[-1])

不复权收盘 1207.68,前复权 1179.76,比值 1.023663,与除权因子完全一致。据此确定复权策略:

数据集

口径

原因

分钟存档

不复权

不随新除权事件变化,可只追加

除权因子表

每日同步

用于按需计算复权价

研究视图

由存档×因子计算

避免拼接不同时点拉取的前复权数据

前复权以最新价为锚,每次除权都会整体改写历史价格。若把不同时间拉取的前复权分钟数据直接拼接,在除权日前后会出现价格断层。存不复权、算复权,是分钟库长期维护成本最低的方案。

七、存储与分区

分钟数据量大,建议按「周期/交易日/标的」分区,文件名中写明口径,例如 min5/20261030/600519.SH_raw.parquet。查询时按日期分区裁剪,单日全市场的分钟数据可以独立重建,不影响其他日期。

八、异常场景的处理规则

规范只覆盖正常交易日是不够的,入库任务还要能识别几类异常,否则校验会频繁误报:

场景

表现

处理规则

全天停牌

当日无分钟数据,日线也无记录

记为停牌,不触发重拉

盘中临时停牌

分钟根数少于 241,但成交量加总仍等于日线

根数校验降级为告警,总量校验仍为强校验

新股上市首日

价格波动大,涨跌幅阈值失效

跳过跳变校验,保留价格关系校验

除权当日

前复权价格整体改写

存档不受影响,仅重建研究视图

数据延迟到达

收盘后立即拉取,末根尚未生成

设置延迟窗口,收盘后间隔一段时间再执行

实践中最有用的是把「强校验」和「告警」分开:总量一致性、标签约定属于强校验,失败即拒绝入库;根数、跳变属于告警,记录后由人工确认。这样既能保证数据正确,也不会因为个别停牌股阻塞整批任务。

另外建议为每次入库生成一条元数据记录,包括标的、交易日、周期、复权口径、根数、成交量合计、拉取时间和校验结果。出现问题时,可以直接按元数据定位到具体批次,而不是重新比对原始文件。

九、总结

分钟级数据入库的核心是把隐含约定显式化:标签用结束时刻、集合竞价归并进第一根、存档不复权并配套除权因子,再用根数、总量和价格三类校验兜底。按这套规范入库后,合成周期与源数据逐根一致,跨数据源比对时的差异也能快速定位到具体原因。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、目标与约束
  • 二、数据流
  • 三、时间标签约定
  • 四、集合竞价归并与周期合成
  • 五、一致性校验
  • 六、分钟级复权一致性
  • 七、存储与分区
  • 八、异常场景的处理规则
  • 九、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档