🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

如何在 JoinQuant 聚宽平台修正 MACD 数据计算偏差?

joinquant | 发布时间: 2026/6/24
以下内容由 EasyQuant 生成。

问题描述

如何修正MACD数据

计算任意周期下的MACD数据,假如起始时间不是该股票的上市首日,则用公式计算所得MACD数据,必然与各大交易软件的MACD数据,存在微小的偏差。
聚宽现在没有直接提供MACD数据下载。
如果才能修正偏差?

解决方案

MACD 数据偏差产生的原因

在量化交易中,MACD(平滑异同移动平均线)是基于 EMA(指数移动平均线)计算的。EMA 的计算公式具有无限递归的特性:今天的 EMA 值依赖于昨天的 EMA 值。理论上,要得到绝对精确的 MACD 值,必须从该股票上市的首日开始计算。

各大交易软件(如通达信、同花顺)通常在本地缓存了从上市首日开始的完整 K 线数据,因此其 MACD 计算是连贯的。而在量化回测或研究中,为了提高计算效率,我们通常只获取所需时间段的数据(例如过去 60 天)。此时,第一天的 EMA 只能用 SMA(简单移动平均)或当天的收盘价来代替,这就导致了初始误差。虽然 EMA 的权重会随时间指数衰减,但如果获取的数据量不够长,这个误差就会一直传递下来,表现为与交易软件的微小偏差。

修正 MACD 偏差的解决方案

在 JoinQuant(聚宽)平台上,虽然没有直接提供现成的 MACD 绝对值下载,但我们可以通过**“增加数据预热期(Warm-up Period)”**的方法来完美消除这种偏差。

核心思路:增加数据获取长度

由于 EMA 的历史权重呈指数级衰减,距离当前时间越远的数据,对当前 EMA 值的影响越小。通常情况下,往前多获取 150 到 250 根 K 线数据作为“预热期”进行计算,计算完成后再截取你真正需要的时间段,其结果就能与各大交易软件保持高度一致(误差通常在小数点后四位以外,可忽略不计)。

Python 代码实现方案

我们可以结合聚宽的 get_barsget_price API 以及 talib 库来实现精确的 MACD 计算。

示例代码:

import jqdata
import talib
import pandas as pd

def get_accurate_macd(security, end_dt, count, unit='1d', fastperiod=12, slowperiod=26, signalperiod=9):
    """
    获取精确的 MACD 数据
    :param security: 股票代码,如 '000001.XSHE'
    :param end_dt: 截止时间
    :param count: 实际需要获取的 MACD 数据长度
    :param unit: K线周期,如 '1d', '60m'
    :return: 包含 macd, macdsignal, macdhist 的 DataFrame
    """
    # 核心:多获取 200 根 K 线作为预热期,消除 EMA 初始误差
    warm_up_count = 200 
    total_count = count + warm_up_count
    
    # 获取历史 K 线数据
    df = get_bars(security, count=total_count, unit=unit, fields=['date', 'close'], end_dt=end_dt, df=True)
    
    if df.empty or len(df) < total_count:
        # 如果上市时间不足 total_count,则有多少取多少,此时误差不可避免,但已是理论最优
        pass
        
    # 使用 talib 计算 MACD
    # 注意:talib.MACD 返回的 macdhist 是 (macd - macdsignal),而国内软件通常是 (macd - macdsignal) * 2
    macd, macdsignal, macdhist = talib.MACD(df['close'].values, 
                                            fastperiod=fastperiod, 
                                            slowperiod=slowperiod, 
                                            signalperiod=signalperiod)
    
    # 将结果存入 DataFrame
    df['macd'] = macd
    df['macdsignal'] = macdsignal
    df['macdhist'] = macdhist * 2  # 乘以 2 以对齐国内交易软件的 MACD 柱状图
    
    # 截取实际需要的长度(去掉预热期的数据)
    result_df = df.iloc[-count:].copy()
    result_df.set_index('date', inplace=True)
    
    return result_df[['macd', 'macdsignal', 'macdhist']]

# --- 使用示例 (在研究环境或回测中调用) ---
# 获取平安银行最近 5 天的精确 MACD 数据
# macd_data = get_accurate_macd('000001.XSHE', end_dt='2023-10-01', count=5)
# print(macd_data)

方案优势

  1. 高精度:多取 200 根 K 线足以让 EMA 的初始误差衰减到极小值,计算结果与通达信、同花顺等软件基本无异。
  2. 灵活性:支持任意周期(如 1d, 60m, 5m),只需调整 get_barsunit 参数即可。
  3. 性能可控:虽然多取了 200 根数据,但对于 talib 的 C 语言底层计算来说,性能损耗微乎其微,完全可以满足量化回测和实盘的需求。

补充说明:聚宽因子库中的 MACD

如果您只是需要使用 MACD 作为选股因子,聚宽的 jqlib.technical_analysis 库中提供了 MACDC 因子。但请注意,聚宽官方的 MACDC 因子定义为:MACD(SHORT=12, LONG=26, MID=9) / 今日收盘价。它除以了收盘价进行了无量纲化处理,如果您需要原始的绝对数值,建议使用上述 talib + 预热期的方法自行计算。