3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
您的理解非常准确!关于EMA(指数移动平均线)的计算,以下是详细的解答:
您理解得完全正确。在 EMA(X, 12) 中,12 并不意味着只取前12天的数据来计算。EMA 是一种具有“无限记忆”的指标,理论上它包含了历史上所有的数据,只是越久远的数据权重越小(呈指数级衰减)。
公式 Y = [2X + (N-1)Y'] / (N+1) 可以改写为更常见的形式:
Y = α * X + (1 - α) * Y'
其中平滑系数 α = 2 / (N+1)。
当 N=12 时,α = 2/13,1-α = 11/13。所以 N 的唯一作用就是确定当日数据和上一周期EMA值的权重分配。当日数据的权重是 2/13,上一周期EMA的权重是 11/13。
如果数据不足12天,但您仍要计算 EMA(X, 12),权值依然是 2/13 和 11/13,不会改变。
这里的关键在于初始值(第一个Y')是如何确定的。通常有两种处理方式:
Y = (2/13)*X + (11/13)*Y' 迭代计算。即使只有3天数据,第2天和第3天也是用这个固定权重算的。在 JoinQuant 量化平台中,您可以通过 pandas 或 talib 库来轻松计算 EMA。
pandas 的 ewm 方法默认采用第一天数据作为初始值,权重固定。
import pandas as pd
import jqdata
def handle_data(context, data):
# 获取过去5天的收盘价(假设数据不足12天)
prices = attribute_history('000001.XSHE', 5, '1d', ['close'])['close']
# 计算 EMA(12)
# span=12 等价于 α = 2/(12+1)
# adjust=False 表示严格按照 Y = α*X + (1-α)*Y' 迭代,不进行早期权重的动态调整
ema_12 = prices.ewm(span=12, adjust=False).mean()
log.info("最新 EMA(12) 值为: %s" % ema_12[-1])
talib 是量化界常用的技术指标库,但它的默认行为是:如果数据少于 N 天,会返回 NaN(空值)。
import talib
import numpy as np
import jqdata
def handle_data(context, data):
# talib 计算 EMA(12) 至少需要 12 天的数据
prices = attribute_history('000001.XSHE', 15, '1d', ['close'])['close']
# 计算 EMA
ema_12 = talib.EMA(prices.values, timeperiod=12)
log.info("最新 EMA(12) 值为: %s" % ema_12[-1])
总结:您的理解非常透彻,N 就是用来计算平滑系数的。在编写量化策略时,如果遇到新上市的股票(数据不足N天),建议使用 pandas.ewm(span=N, adjust=False).mean(),这样即使数据不足也能计算出合理的 EMA 值。