问题描述
查询贵州茅台股票,调用官方接口拿到2020-11-18的ema,然后根据2020-11-19的收盘价计算2020-11-19的ema,计算得到1700.229,这个和调用接口得到的1697.759不一致,请问这要怎么解决呢?以下是计算方法
2020-11-18调用接口得到的ema: EMA(["600519.XSHG"], "2020-11-18", timeperiod=12, unit="1d", include_now=True): {'600519.XSHG': 1696.599762571008}
2021-11-19调用接口得到的ema: EMA(["600519.XSHG"], "2020-11-19", timeperiod=12, unit="1d", include_now=True): {'600519.XSHG': 1697.7596576572978}
查询2020-11-18到2020-11-27的bar: get_bars(['600519.XSHG'], 8, unit='1d',
fields=['date', 'open', 'close', 'high', 'low', 'volume', 'money'], include_now=False,
end_dt=datetime.datetime(2020, 11, 30)):
date open close high low volume money
0 2020-11-18 1715.00 1693.65 1720.53 1683.16 3517895.0 5.973147e+09
1 2020-11-19 1684.50 1720.19 1725.00 1680.60 2781576.0 4.767509e+09
2 2020-11-20 1720.00 1719.96 1736.00 1712.65 2187466.0 3.771895e+09
3 2020-11-23 1771.01 1790.21 1809.90 1771.01 6663724.0 1.192687e+10
4 2020-11-24 1769.99 1763.50 1782.50 1751.47 3246536.0 5.736960e+09
5 2020-11-25 1761.50 1726.88 1768.88 1724.00 2822632.0 4.910541e+09
6 2020-11-26 1726.00 1734.39 1739.99 1725.18 2322830.0 4.027749e+09
7 2020-11-27 1732.66 1737.90 1740.03 1718.00 2156861.0 3.737698e+09
其中2020-11-19的收盘价为1720.19
通过2020-11-18的ema和2020-11-19的收盘价计算ema:1696.59976257100811/13+1720.192/13=1700.229029867776, 这个和官方接口调用得到的1697.7596576572978不一致
解决方案
您好!导致您手动计算的 EMA 与官方接口返回的 EMA 不一致的根本原因在于价格的复权处理。
问题原因解析
您的 EMA 计算公式本身是完全正确的:
EMA_today = EMA_yesterday * 11/13 + Close_today * 2/13
差异出在 Close_today(2020-11-19 的收盘价)上:
- 官方 EMA 接口:JoinQuant 的官方技术指标接口(如
EMA、MACD等)在计算时,默认使用的是前复权价格。因为只有使用复权价格,才能消除分红、送股等除权除息事件对技术指标造成的跳空影响。 - 您的
get_bars调用:在您的get_bars代码中,没有显式指定fq_ref_date参数。在研究环境中,如果不指定该参数,默认获取的可能是不复权价格(您获取到的 1720.19 即为茅台当天的真实不复权收盘价)。
我们可以反推一下官方接口使用的收盘价:
1696.59976 * (11/13) + X * (2/13) = 1697.759657
解得 X ≈ 1704.14。
这说明官方接口在计算 2020-11-19 的 EMA 时,使用的是前复权收盘价(约 1704.14 元),而不是不复权收盘价(1720.19 元)。
解决方法
要让手动计算的结果与官方接口一致,您需要在获取 K 线数据时,确保获取的是前复权价格。可以通过在 get_bars 中设置 fq_ref_date 参数来实现。
修改后的代码示例:
import datetime
from jqdata import *
# 获取前复权数据,fq_ref_date 设置为当前日期(与官方指标库默认的复权基准一致)
bars = get_bars(
['600519.XSHG'],
8,
unit='1d',
fields=['date', 'open', 'close', 'high', 'low', 'volume', 'money'],
include_now=False,
end_dt=datetime.datetime(2020, 11, 30),
fq_ref_date=datetime.datetime.now() # 关键参数:指定复权基准日获取前复权数据
)
print(bars)
获取到前复权的 close 价格后,再代入您的公式 EMA_yesterday * 11/13 + Close_today * 2/13,计算出的结果就会与官方接口 EMA 的返回值完全一致了。
总结:在量化交易中计算任何依赖历史价格的技术指标(如均线、MACD、BOLL 等)时,都务必使用前复权数据,以保证指标的连续性和准确性。