🚀 AI 一键生成 joinquant 策略代码

JoinQuant 聚宽平台嵌套 EMA(指数移动平均)指标计算指南

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

问题描述

请教一下,EMA指标中继续嵌套EMA指标怎么写?

比如EMA1返回了一个值,需要将EMA1返回的值继续在EMA2中继续使用,这个代码应该怎么写?

问了聚宽的客服,他们自己的这个代码:
EMA(security_list, check_date, timeperiod=30, unit = '1d', include_now = True, fq_ref_date = None)

不支持这种操作

解决方案

聚宽官方提供的 EMA 函数(属于 jqlib.technical_analysis)确实是高度封装的,它的输入必须是股票代码(security_list),因此无法直接将一个计算好的数值序列再次传入该函数。

要实现嵌套 EMA(即对 EMA 的结果再求 EMA),我们需要绕过官方的封装函数,直接获取历史价格数据,然后使用 Python 的数据处理库(如 pandastalib)来进行计算。

以下提供两种最常用的实现方法:

方法一:使用 Pandas 的 ewm 方法(最推荐)

pandas 是 Python 数据分析的核心库,它的 ewm (Exponential Weighted functions) 方法非常适合计算 EMA,且支持对任意 Series 序列进行连续操作,完美契合嵌套计算的需求。

import pandas as pd
from jqdata import *

def get_nested_ema_pandas(security, check_date, period1=12, period2=26):
    """
    使用 Pandas 计算嵌套 EMA
    :param security: 股票代码
    :param check_date: 截止日期
    :param period1: 第一层 EMA 的周期
    :param period2: 第二层 EMA 的周期
    :return: 最新的 EMA1 和 嵌套 EMA2 的值
    """
    # 1. 获取历史收盘价数据
    # 注意:计算 EMA 需要足够的历史数据来消除初始值的影响,建议 count 设置为最大周期的 3-5 倍以上
    df = get_price(security, end_date=check_date, count=150, fields=['close'])
    close_prices = df['close']
    
    # 2. 计算第一层 EMA
    # adjust=False 保证计算公式与传统炒股软件的 EMA 公式一致
    ema1_series = close_prices.ewm(span=period1, adjust=False).mean()
    
    # 3. 计算第二层 EMA(嵌套计算)
    # 直接对第一层的结果 ema1_series 再次调用 ewm
    ema2_series = ema1_series.ewm(span=period2, adjust=False).mean()
    
    # 4. 返回最新一天的值
    return ema1_series.iloc[-1], ema2_series.iloc[-1]

# 测试调用
# ema1_val, ema2_val = get_nested_ema_pandas('000001.XSHE', '2023-10-10', 12, 26)
# print(f"EMA1: {ema1_val}, 嵌套EMA2: {ema2_val}")

方法二:使用 TA-Lib 库

talib 是量化领域最著名的技术指标库,聚宽环境已经内置了该库。它的 EMA 函数接受 numpy 数组作为输入,因此也可以轻松实现嵌套。

import talib
import numpy as np
from jqdata import *

def get_nested_ema_talib(security, check_date, period1=12, period2=26):
    """
    使用 TA-Lib 计算嵌套 EMA
    """
    # 1. 获取历史数据
    df = get_price(security, end_date=check_date, count=150, fields=['close'])
    # talib 需要 numpy array 格式的数据
    close_prices = df['close'].values
    
    # 2. 计算第一层 EMA
    ema1_array = talib.EMA(close_prices, timeperiod=period1)
    
    # 3. 计算第二层 EMA(嵌套计算)
    # 注意:talib.EMA 计算结果的前 period1-1 个值会是 NaN
    # talib 可以自动处理输入数组中的 NaN,直接传入即可
    ema2_array = talib.EMA(ema1_array, timeperiod=period2)
    
    # 4. 返回最新一天的值
    return ema1_array[-1], ema2_array[-1]

核心注意事项

  1. 数据长度(count 参数):EMA(指数移动平均)是一个具有“无限长记忆性”的指标,今天的值受昨天值的影响,昨天受前天影响。因此,获取的历史数据长度(count)必须足够长。强烈建议 count 的值至少设置为 period1 + period2 的 3 到 5 倍(例如周期是 12 和 26,count 至少取 150),否则计算出的最新值会与同花顺/通达信等软件产生较大误差。
  2. Pandas 的 adjust=False:在使用 Pandas 计算时,务必加上 adjust=False 参数,这样其底层计算逻辑才会与传统金融软件的 EMA 逻辑(Y = [2*X + (N-1)*Y'] / (N+1))保持一致。
  3. 回测中的应用:在 handle_data 中调用时,check_date 可以直接传入 context.current_dt