问题描述
平台上有个MA的计算公式,如下:
MA(security_list, check_date, timeperiod=5),
请问下,这里面的security_list,我可以换成其它的指标嘛?
我试了下用mean(),但是结果与通达信的数据差得好大。
解决方案
1. MA 函数的 security_list 可以换成其他指标吗?
在 JoinQuant 的技术指标库(jqlib.technical_analysis)中,MA(security_list, check_date, timeperiod=5) 这个函数的底层逻辑是**专门针对股票代码(Security)**去获取其历史收盘价,然后再计算移动平均的。因此,你不能直接把 security_list 替换成一个已经计算好的指标序列或数值列表,否则函数会因为无法识别股票代码而报错。
2. 如何对自定义指标求移动平均(MA)?
如果你已经计算出了某个自定义指标的时间序列(例如一个 pandas.Series 或 list),想要对它求移动平均,最标准且高效的方法是使用 Python 数据分析库 Pandas 的 rolling 方法。
代码示例:
import pandas as pd
# 假设 custom_indicator 是你计算出来的一个包含历史数据的 pandas.Series
# 计算5日简单移动平均 (SMA)
ma_5 = custom_indicator.rolling(window=5).mean()
# 获取最新一天的 MA 值
latest_ma = ma_5.iloc[-1]
3. 为什么用 mean() 算出来的结果和通达信差很大?
如果你自己用 mean() 算出来的 MA 结果与通达信软件上的数据差异很大,通常是由以下几个原因造成的:
A. 复权方式不一致(最常见原因)
- JoinQuant 默认机制:在回测或获取数据时,JoinQuant 默认提供的是前复权数据。如果你开启了
set_option('use_real_price', True),通过attribute_history或get_price拿到的依然是基于当天的前复权价格。 - 通达信机制:通达信软件默认可能显示的是不复权价格,或者你对比时通达信使用的是不同基准日的前复权。复权因子的差异会导致历史价格不同,从而算出来的 MA 均线值产生巨大差异。
- 解决方法:确保两边使用完全相同的复权方式。可以在 JoinQuant 中使用
get_price(..., fq=None)获取不复权数据进行对比验证。
B. 停牌数据的处理方式不同
- JoinQuant 默认机制:在获取历史数据时(如
attribute_history),默认skip_paused=True(跳过停牌日)。但如果使用get_price且未设置跳过,停牌日会用前一天的收盘价填充。 - 通达信机制:通达信的 K 线图通常是直接跳过停牌日的。如果两边对停牌日的处理不一致,计算 MA 时的“过去 N 天”所涵盖的实际交易日就会不同。
- 解决方法:检查标的在计算周期内是否有停牌,确保 JoinQuant 取数据时
skip_paused的设置与通达信的展示逻辑一致。
C. 计算公式的差异
- 通达信中的
MA是简单移动平均(Simple Moving Average)。如果你在 JoinQuant 中不小心使用了EMA(指数移动平均)或VWAP(成交量加权平均价),结果自然不同。 - 确保你使用的是
rolling(window=N).mean(),这等价于通达信的MA(C, N)。
总结建议
对于自定义指标的均线计算,放弃内置的 MA 函数,直接使用 pandas 的 rolling().mean()。同时,严格核对 JoinQuant 获取底层数据时的复权参数(fq)和停牌处理参数(skip_paused),使其与通达信的设置保持一致,数据差异自然就会消除。