🚀 AI 一键生成 joinquant 策略代码

EXPMA和EMA的区别是什么?为什么聚宽API调用结果与手动计算不同?

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

问题描述

EXPMA和EMA的区别

在技术分析因子中,有一个EXPMA,有一个EMA,这两者有什么不同嘛?我查阅了一些文档,很多说其实是一个指标。但我调用了聚宽的API后,发现两者的值是不同,且和我自己算的都不同,
可否告知一下两者的区别在哪里?

解决方案

在金融技术分析中,EMA(Exponential Moving Average,指数移动平均)EXPMA(Exponential Moving Average,指数平滑移动平均)在纯数学理论上确实是同一个指标。它们的计算核心逻辑都是对历史价格进行指数加权,越近的价格权重越大。

然而,在实际的量化平台(如聚宽 JoinQuant)和不同的炒股软件(如同花顺、通达信)中,调用API得到的值往往不同,甚至与你手动计算的值也不同。这主要由以下四个核心原因导致:

1. 聚宽因子库中的特殊定义(标准化处理)

在聚宽的因子库(如技术因子)中,很多指标为了消除量纲、方便截面比较,进行了标准化处理。根据聚宽API文档:

  • EMA5 因子的定义是:5日指数移动均线 / 今日收盘价
  • EMAC10 因子的定义是:10日指数移动均线 / 今日收盘价

结论:聚宽因子库直接返回的 EMA 因子往往是一个比值(Ratio),而不是绝对的价格数值。如果你手动计算的是绝对价格(比如 15.5 元),而API返回的是 0.98(表示均线在收盘价下方),两者自然完全不同。

2. 初始值(起点)的设定差异

EMA 是一个无限脉冲响应(IIR)滤波器,它的当前值依赖于上一期的值:
EMA(今日) = α * 今日收盘价 + (1 - α) * EMA(昨日)

  • 差异点:第一天的 EMA(昨日) 怎么取?
  • 常见做法A:取第一天的收盘价作为初始 EMA。
  • 常见做法B:取前 N 天的简单移动平均(SMA)作为第 N 天的初始 EMA,从第 N+1 天开始指数加权。
    不同的软件和库(如 talibpandas.ewm、通达信)在初始值的设定上存在微小差异,这会导致后续计算结果的偏移。

3. 历史数据长度(预热期)的影响

由于 EMA 包含历史所有数据的衰减权重,计算时截取的历史数据长度越长,当前的值越精确

  • 如果你手动计算时只取了过去 60 天的数据来算 EMA(12)。
  • 而聚宽底层计算时使用了过去 250 天甚至上市以来的所有数据。
    两者的结果在小数点后几位必然会出现差异。通常建议至少使用 3 * N5 * N 天的历史数据作为“预热期(Warm-up)”来消除初始值带来的误差。

4. 复权方式的不同

聚宽平台默认使用**前复权(pre-adjusted)**数据。如果你在本地手动计算时,使用的是不复权(真实价格)或者后复权数据,遇到股票分红、送转时,计算出的均线数值会产生巨大差异。


💡 解决方案:如何在聚宽中计算标准的绝对值 EMA?

如果你需要获取与传统炒股软件一致的、绝对价格数值的 EMA,建议不要直接调用因子库的标准化因子,而是通过获取历史价格后,使用 talibpandas 自行计算:

import pandas as pd
import talib

def handle_data(context, data):
    # 1. 获取过去足够长的数据(例如计算12日EMA,获取60天数据作为预热)
    prices = attribute_history('000001.XSHE', 60, '1d', ['close'], df=True)
    
    # 2. 使用 talib 计算标准 EMA(绝对价格)
    ema_talib = talib.EMA(prices['close'].values, timeperiod=12)
    
    # 3. 或者使用 pandas 计算(adjust=False 接近通达信算法)
    ema_pandas = prices['close'].ewm(span=12, adjust=False).mean()
    
    # 打印最新一天的标准 EMA 值
    log.info("TA-Lib EMA: %s", ema_talib[-1])
    log.info("Pandas EMA: %s", ema_pandas.iloc[-1])

总结:EXPMA 和 EMA 理论上是同一个东西。你遇到的差异主要是因为聚宽因子库对 EMA 做了除以收盘价的标准化处理,以及初始值/数据长度/复权方式的计算细节不同。使用 talib.EMA 结合足够长的历史前复权数据,即可得到你期望的标准绝对值。