问题描述
复权数据作为基础数据之一,为什么 QMT 都能是错的?
以 600375.SH (ST 汉马) 为例,它在 2024-12-26 这天发生了复权,具体的复权因子应该大概是 1.064,但我观察 QMT 的数据发现:
(1)头几天,QMT 当时显示的是 2.4 这个值,
(2)12-30 当时又试了下, 发现 QMT 干脆删除了这天的复权信息
(3)目前最新的数据又变了,直接显示 1 ...
解决方案
非常理解您的困扰。复权数据作为量化回测和实盘交易的基础,其准确性至关重要。您在 600375.SH (ST 汉马) 上观察到的 get_divid_factors 数据反复变动(从 2.4 到消失,再到 1),确实反映了底层数据处理上的一些问题。
一、 为什么 QMT 的复权数据会出现这种异常波动?
这种情况通常由以下几个原因导致,尤其是在处理 ST 股票或发生复杂公司事件时:
- 复杂公司事件(如破产重整、资本公积转增):ST 汉马在 2024 年底涉及重整计划,资本公积转增股本等操作。这类非典型的除权除息事件,交易所的公告解析和数据提供商的算法在初期容易出现偏差。2.4 可能是初期算法错误计算的预估值。
- 数据源的修正与同步延迟:QMT 的底层数据依赖于上游数据供应商。当供应商发现数据异常时,会进行修正(例如您观察到的删除记录,或者暂时重置为 1)。这种修正推送到客户端需要时间,且有时会经历多次迭代。
- 本地数据缓存未更新:QMT 客户端为了提高运行速度,会将大量数据缓存在本地。如果服务器端数据已修正,但本地缓存未被正确覆盖或清理,就会导致读取到的数据依然是旧的或错乱的。
二、 解决方案与排查步骤
面对这种底层数据异常,您可以采取以下步骤进行处理和规避:
1. 强制清理并重新下载本地数据(最重要)
很多时候数据变来变去是因为本地缓存错乱。请尝试手动清理并重新下载:
- 打开 QMT 客户端,进入 【数据管理】。
- 找到 除权除息数据 和 日线行情数据。
- 清除
600375.SH的相关数据,然后重新补充下载最新数据。
2. 向官方/券商提交 Bug 反馈
由于这是底层数据源的问题,最根本的解决方式是让官方修复。建议您通过券商的专属服务群或 QMT 官方渠道,直接提交该股票代码和具体日期的复权异常情况,要求技术人员核实上游数据。
3. 代码层面的替代方案:通过行情反推复权因子
如果 get_divid_factors 接口暂时不可靠,而您又急需准确的复权因子,可以通过获取同一时间段的复权收盘价和不复权收盘价,自行反推复权因子。QMT 的行情数据(get_market_data_ex)通常比单独的除权除息字典修复得更快。
Python 替代方案示例代码:
#coding:gbk
def init(ContextInfo):
ContextInfo.stock = '600375.SH'
# 订阅数据,确保本地有最新行情
ContextInfo.subscribe_quote(ContextInfo.stock, '1d', 'none')
ContextInfo.subscribe_quote(ContextInfo.stock, '1d', 'front')
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
stock = ContextInfo.stock
# 1. 获取不复权数据
df_none = ContextInfo.get_market_data_ex(
['close'], [stock], period='1d', count=10, dividend_type='none'
)
# 2. 获取前复权数据
df_front = ContextInfo.get_market_data_ex(
['close'], [stock], period='1d', count=10, dividend_type='front'
)
if stock in df_none and stock in df_front:
close_none = df_none[stock]['close']
close_front = df_front[stock]['close']
print(f"--- {stock} 最近10日复权因子推算 ---")
# 遍历日期,计算复权因子 (前复权价格 / 不复权价格)
# 注意:实际复权因子计算可能涉及等比或精确的除权公式,这里提供一个近似的比例参考
for date in close_none.index:
if date in close_front.index:
p_none = close_none[date]
p_front = close_front[date]
if p_none != 0:
# 简单的价格比值,反映复权影响
factor_approx = p_front / p_none
print(f"日期: {date}, 不复权收盘: {p_none:.2f}, 前复权收盘: {p_front:.2f}, 推算比例: {factor_approx:.4f}")
总结:
量化交易中,数据清洗和容错处理是必不可少的一环。对于 ST 股票或发生重大重组的股票,其财务和复权数据往往是“重灾区”。建议在策略中加入对异常复权因子(如突变过大)的过滤逻辑,或者在关键节点使用行情数据进行交叉验证。