0 引言
KDJ指标是最为常见的指标之一,股票每日的K线数据通过Tushare、Baostock等平台能够获取到个股及指数的Open、High、Low、Close、Volume等数据,KDJ、MACD等技术指标虽然同花顺等财经网站都算好了,但是这写指标确没有接口给“量化宽客”们使用。
1 计算公式
KDJ计算主要有4步:
(1)计算RSV:RSV=(Close(当日值)-Low(9日最低值)) / (High(9日最高值)-Low(9日最低值))
(2)计算K:K=ema(RSV, com=2),ema为指数移动平均,参数com取2;
(3)计算D:D=ema(K, com=2),ema为指数移动平均,参数com取2;
(4)计算J:J=3.0*K-2.0*D
2 Python计算实现
Python实现KDJ指标的计算,主要基于Pandas库实现计算:
2.1 获取数据:
通过Baostock、Tushare、YahooFinance获取数据,这里以Baostock为例:
import baostock as bs
import pandas as pd
code = 'sh.600036'
start_date = '2021-01-01'
end_date = '2021-10-01'
#Step1: 获取数据
lg = bs.login()
rs = bs.query_history_k_data_plus(code,
"date,code,open,high,low,close,volume",
start_date=start_date, end_date=end_date, frequency="d", adjustflag='2')#注意adjustflag取2为前复权
data_list = []
while (rs.error_code == '0') & rs.next():
data_list.append(rs.get_row_data())
df = pd.Dataframe(data_list, columns=rs.fields)
df[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']].astype(
'float64')
df = df.rename(columns={'date': 'datetime'})
df.index = pd.DatetimeIndex(df['datetime'])
bs.logout()
得到结果如下:
2.2 基于Python计算KDJ
利用Python的Pandas库进行计算:
lowList = df['low'].rolling(9).min() #计算low值9日移动最低 lowList.fillna(value=df['low'].expanding().min(), inplace=True) highList = df['high'].rolling(9).max() #计算high值9日移动最高 highList.fillna(value=df['high'].expanding().max(), inplace=True) rsv = (df.loc[:, 'close'] - lowList) / (highList - lowList) * 100 df.loc[:, 'kdj_k'] = rsv.ewm(com=2).mean() df.loc[:, 'kdj_d'] = df.loc[:, 'kdj_k'].ewm(com=2).mean() df.loc[:, 'kdj_j'] = 3.0 * df.loc[:, 'kdj_k'] - 2.0 * df.loc[:, 'kdj_d']
得到结果:
对比财经网站结果,以2021-9-30为例,K、D、J三个指标与计算结果一致。
3 Ta-lib计算实现发现用Python实现代码量比较多,是不是不够优雅,那么我们用股票技术指标分析利器Ta-lib进行尝试(Ta-lib安装自行百度):
Ta-lib计算KDJ的函数是STOCH,但是这个函数参数较多,按照默认配置是无法计算出和国内一致的结果:
def STOCH(*args, **kwargs): # reliably restored by inspect
"""
STOCH(high, low, close[, fastk_period=?, slowk_period=?, slowk_matype=?, slowd_period=?, slowd_matype=?])
Stochastic (Momentum Indicators)
Inputs:
prices: ['high', 'low', 'close']
Parameters:
fastk_period: 5
slowk_period: 3
slowk_matype: 0
slowd_period: 3
slowd_matype: 0
Outputs:
slowk
slowd
"""
pass
主要参数是这几个:
(1)fastk_period:对应9日移动平均,这里取值为9;
(2)slowk_period: 这个指标取值是计算的关键:
计算公式中提到了 “K=ema(RSV, com=2),ema为指数移动平均,参数com取2”
com=2,对应slowk_period应该取多少?通过查看Pandas官方教程:
com=2时,α=1/3 , 则span=5;
对应slowk_period=5;
(3)slowk_matype:
通过查看Ta-lib 中matype的类型说明:
MA_Type: 0=SMA, 1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3 (Default=SMA)
指数移动平均:slowk_matype应取1。
(4)slowd_period、slowd_matype同上。
(5)最后参数配置就都有了,直接上代码:
import talib
df['talib_K'], df['talib_D'] = talib.STOCH(df['high'].values,
df['low'].values,
df['close'].values,
fastk_period=9,
slowk_period=5,
slowk_matype=1,
slowd_period=5,
slowd_matype=1)#计算kdj的正确配置
df.loc[:, 'talib_J'] = 3.0 * df.loc[:, 'talib_K'] - 2.0 * df.loc[:, 'talib_D']
结果展示:
和之前的计算完全一致。(此结果为:2021.10.7前复权计算结果)
4 计算速度对比把计算开始时间改为2002.4.9(600036:招商银行上市日),进行计算:
Pandas totally cost: 0.0050699710845947266
Talib totally cost: 0.0010001659393310547
| 计算方法 | 天数 | 计算时长 |
| Pandas | 4735天 | 0.00507秒 |
| Talib | 4735天 | 0.00100秒 |
总体Talib实现KDJ指标计算不仅更加优雅,而且速度比Pandas更快,小伙伴以后计算KDJ指标可以选择Talib了。



