问题描述
发现一个问题,每日最低价竟然在当日每分钟的最低价中找不到。
例如:2022-03-07的000622.XSHE
查询当日最低价是4.20,而查询当日每分钟的价格,最低价出现过4.64。
查当日最低价:
temp0b = get_price(['000622.XSHE'], end_date=datetime.datetime(2022, 3, 7, 15, 0, 0),
count=1, frequency='daily', panel=False, fields=['open','close','high','low'])
查当日每分钟最低价:
temp0c = get_price(['000622.XSHE'], end_date=datetime.datetime(2022, 3, 7, 15, 0, 0),
count=241, frequency='minute', panel=False, fields=['open','close','high','low'])
那这个4.20是怎么来的呢?
解决方案
在量化数据分析中,遇到日线极值(最高价/最低价)与分钟线极值不一致的情况,通常是由以下几个核心原因导致的。针对您提到的 000622.XSHE 在 2022-03-07 的数据差异(日线最低 4.20,分钟线最低 4.64),可以通过以下几个维度进行排查和理解:
1. 默认的复权机制(最常见原因)
在 JoinQuant 的 get_price 函数中,参数 fq(复权选项)的默认值是 'pre'(前复权)。
- 日线与分钟线的复权处理差异:在某些特定情况下(如除权除息日附近,或者底层数据源在日线和分钟线复权因子的应用精度上),前复权计算可能会导致日线和分钟线的历史价格出现偏差。
- 排查方法:强烈建议在对比日线和分钟线绝对价格时,关闭复权(设置
fq=None),获取真实的交易价格进行对比。
测试代码:
# 获取不复权的日线数据
temp0b_real = get_price(['000622.XSHE'], end_date=datetime.datetime(2022, 3, 7, 15, 0, 0),
count=1, frequency='daily', panel=False, fields=['open','close','high','low'], fq=None)
# 获取不复权的分钟线数据
temp0c_real = get_price(['000622.XSHE'], end_date=datetime.datetime(2022, 3, 7, 15, 0, 0),
count=240, frequency='minute', panel=False, fields=['open','close','high','low'], fq=None)
print("真实日线最低价:", temp0b_real['low'].min())
print("真实分钟线最低价:", temp0c_real['low'].min())
注:A股一天只有240根分钟线,您的代码中 count=241 会把前一个交易日(3月4日)的最后一分钟也取进来。
2. 集合竞价的影响
A股的日线最高价和最低价是包含全天所有成交的,包括 9:15 - 9:25 的集合竞价。
- 在 JoinQuant 的分钟线数据中,9:25 的集合竞价成交数据会被合并到 9:31 的第一根分钟 Bar 中(其数据时间代表 09:25:00~09:30:59)。
- 如果当天的最低价 4.20 是在集合竞价阶段产生的,那么它应该体现在 9:31 这根分钟线的
low字段中。您可以单独打印 9:31 的数据进行核对。
3. 停牌或异常数据填充
如果该股票在当天处于停牌状态,或者发生了极端行情:
get_price默认skip_paused=False,停牌时会用前一交易日的收盘价进行填充。- 如果底层数据源在日线和分钟线的清洗规则上存在微小的时间戳对齐差异,也可能导致极值不匹配。不过 4.20 和 4.64 差距接近 10%(通常是一个跌停板的距离),这极大概率是因为复权因子或除权除息导致的。
总结与建议
这个 4.20 极大概率是前复权计算后的价格,而分钟线在提取或复权计算时可能由于精度或复权基准日的差异显示为 4.64。
解决建议:
在编写策略或验证数据时,如果需要严格对齐日内极值,请务必显式指定 fq=None 获取真实价格进行逻辑验证。在实际回测中,建议使用 set_option('use_real_price', True) 开启真实价格撮合模式,以避免复权数据带来的“未来函数”或价格失真问题。