问题描述
最近进行策略回测,用到MACD技术指标,但发现计算出来的结果跟同花顺等软件有细微差别,无论使用talib、numpy还是聚宽的技术分析指标因子库,都是一样。研究一下发现好像是因为复权计算方式不同,聚宽跟同花顺的历史数据是不同的,所以基于这些数据计算得到的MACD肯定是不同的,存在一点点误差,这个问题是不是无解了?
解决方案
聚宽MACD与同花顺等软件存在差异的原因
你观察到的现象非常准确。在量化回测中,使用聚宽(JoinQuant)数据计算出的MACD等技术指标,确实会与同花顺、通达信等传统炒股软件显示的结果存在细微差异。这主要由以下几个原因导致:
1. 复权算法与基准日的差异
这是最核心的原因。MACD等指标是基于历史价格计算的。当股票发生分红、送转时,需要进行复权处理。
- 复权因子差异:不同数据提供商(聚宽、同花顺、Wind等)在计算复权因子时,保留的小数位数、对除权除息日具体处理细节可能略有不同。
- 基准日差异:前复权是以某个特定日期(通常是当前日期)为基准,向后倒推调整历史价格。如果基准日不同,或者在回测过程中基准日随着时间推移而变化(聚宽的动态复权模式),那么在特定历史时刻看到的“前复权价格”绝对值是不同的。
2. MACD指标的“长记忆性”
MACD是基于指数移动平均线(EMA)计算的。EMA的计算公式为:EMA(今日) = α * Price(今日) + (1 - α) * EMA(昨日)。这意味着,理论上今天的EMA值包含了历史上所有价格的信息。虽然历史久远的价格权重会呈指数级衰减,但如果历史复权价格存在微小差异,这种差异会一直传递并累积到今天的MACD计算结果中。
3. 初始值的设定
在计算第一天的EMA时,通常用当天的收盘价或简单移动平均(SMA)作为初始值。不同软件在截取历史数据长度(比如取上市以来的所有数据,还是只取最近几年的数据)和初始值设定上可能存在差异,这也会导致后续计算结果的微小偏移。
这个问题“无解”吗?
如果你的目标是**“让聚宽的MACD数值与同花顺一模一样,精确到小数点后四位”,那么这基本上是无解**的,除非你能完全拿到同花顺的底层未复权数据,并完全复刻其未公开的复权算法和指标初始值设定逻辑。
但是,从量化交易的角度来看,这个问题不需要解,或者说这种差异是可以接受的。
应对策略与量化思维
1. 接受差异,保持内部一致性
量化策略最重要的是逻辑的一致性。只要你在回测、模拟盘和最终的实盘信号生成中,始终使用同一个数据源(例如全部使用聚宽数据),那么这种绝对数值上的微小差异就不会影响策略的有效性。聚宽的 jqlib.technical_analysis 库提供的指标就是为了保证这种内部一致性。
2. 关注趋势与交叉,而非绝对数值
MACD指标的核心用法是判断趋势(零轴上下)和动量变化(金叉/死叉)。复权带来的微小数值误差,极少会改变金叉或死叉的相对形态。即使有影响,最多也只是让交叉信号提前或延后一根K线。如果你的策略因为MACD差了0.01,或者信号差了一天,就从暴利变成巨亏,这说明策略本身极度脆弱,存在严重的过拟合,在真实的、充满噪音的市场中是无法生存的。
3. 鲁棒性测试
一个优秀的量化策略应该具备鲁棒性(Robustness)。你可以尝试在计算MACD时,人为加入一点点随机噪音,看看策略的绩效是否会大幅下降。如果绩效稳定,说明你根本不需要在意聚宽和同花顺之间那一点点数据差异。
4. 极端情况下的处理(不推荐)
如果你有强迫症,非要自己算,你可以通过 get_price(..., fq=None) 获取真实的不复权数据,然后自己根据分红送配信息(可以通过聚宽财务数据获取)编写复权逻辑,再套用 talib 计算。但这不仅费时费力,而且极易引入未来函数或计算错误,得不偿失。
总结: 放弃追求与特定炒股软件的“像素级”对齐。理解数据差异的来源,拥抱量化平台的数据体系,把精力放在提升策略逻辑的鲁棒性上,才是正确的量化研究之道。