特来谢一下帖子,另外补充一下,如果上面的代码计算结果仍对不上,可以把数据的时间段范围拉长,这样数据就能对上了。
下面这个是我们股票软件上的实现公式:
两个公式变量名字有些不同,这里简单说一下
上图的FASTK就是下图的RSV;上图的FASTD在下图没有对应,上图的SLOWK对应下图的K, SLOWD对应下图的D, 上图没有变量J, 因为J=3*K-2*D (George Lane博士的公式说3*D -2*K)
实际上这个函数talib.STOCH只返回了两个变量slowd 和slowk, slowj可有这个两个变量求得。
fastk和fastd是快速随机变量函数talib.STOCH FAST返回的,因为快速随机变量实际应用有问题,很少有软件实现。
软件中的SMA是这样定义的:SMA(X,N,M) X的M日加权移动平均,M为权重,如Y=(XM+Y’(N-M))/N (Y’ 为前一日的Y值);并非talib中的SMA,talib实现的SMA是简单移动平均(Simple Moving Average),这一点要特别注意。
在求得RSV这一步两者是一致的,都是:
RSV =(单日收盘价-最低价集合中的最低价)/ (最高价集合中的最高价-最低价集合中的最低价)*100【观察周期是P1】
对K值的计算,从George Lane博士的公式上看,和软件中的实现也是一致的,软件中的公式是
SMA(RSV,P2,1) , George Lane博士的公式是MA Smoothed FastK over FastPeriod. 意思和公式是一致的,都是在P2 周期对RSV求平滑移动平均。两者的意思是一致的。问题出在具体实现上,因为两个SMA不一样。
STOCH的函数声明是这样的:
slowk, slowd = STOCH(high, low, close, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)
注意有两个参数slowk_matype=0和slowd_matype=0,这两个参数指定使用什么样的ma计算K和D,0代表SMA(Simple Moving Average),这个SMA与股票软件中的那个SMA实现是不一样的。股票软件中实现的SMA实际上是talib中的EMA函数。
talib这样做显然是对ma的计算算法保持开放态度,因此不能说talib求出的K和D值与常用股票软件中不一致就是talib算错了。我相信talib经历了20年的发展,还是经得住时间的考验的。
按照网上一些帖子给出的自己计算K和D的算法:
K = pd.DataFrame(rsv).ewm(com=slowk_period-1).mean()
D = K.ewm(com=slowd_period-1).mean()
经过测试验证这样求的K和D,和我们常用的股票软件上显示的是一致的。这样进一步确定了股票软件上的算法:即是求的指数平均值(Exponential Moving Average).
我们再看看talib中EMA函数的实现算法:
看了talib WMA的实现公式发现,在计算EMA的alpha系数时,使用了span参数,而股票软件中的算法相当于dataframe.ewm()使用了com参数,这样在计算alpha权重系数时会有差别。
这两个参数是可以转换的,由上述alpha系数计算公式可以推导出s=2c+1 , 股票软件的计算公式相当于dataframe.ewm(com=m-1).mean, 代入c=m-1得出,当s=2m-1时,使用talib.EMA(cose,s=2m-1) 计算K和D的值与股票软件一致。
经多方查阅终于找到matype的值了:
matype :0 = SMA, 1=EMA,2=WMA,3=DEMA,4=TEMA,5=TRIMA,6=KAMA,7=MAMA,8=T3
这样就终于搞明白了,要想得到与股票软件中KDJ一样的数据,应这样调用talib.STOCH
这里贴出部分代码:
# 初始化KDJ参数:注意ma_type=1
def init_kdj(self, fastk_period=9, slowk_period=3, slowk_matype=1,
slowd_period=3,
slowd_matype=1):
self.fastk_period = fastk_period
# s=2m-1 ,由com参数换算成span参数
self.slowk_period = 2 * slowk_period - 1
self.slowk_matype = slowk_matype
self.slowd_period = 2 * slowd_period - 1
self.slowd_matype = slowd_matype
调用函数计算KDJ
slowk, slowd = talib.STOCH(high_prices, low_prices, close_prices, self.fastk_period, self.slowk_period,
self.slowk_matype, self.slowd_period,
self.slowd_matype)
slowk = slowk.values
slowd = slowd.values
slowj = 3 * slowk - 2 * slowd
经过测试,果然丝毫不差!
参考资料:
特来谢一下帖子,另外补充一下,如果上面的代码计算结果仍对不上,可以把数据的时间段范围拉长,这样数据就能对上了。
请问,如何在iquant里对kdj的参数进行设置?
若ma_type=0时,则不需要s=2m-1转换
改成1还是不一致。