随机指标(KDJ)又称为随机指数(The Random Index),是一种用来分析市场中超买或者超卖现象的指标。它最早应用于期货市场,后来在股票市场中被众多投资者广泛使用。
KDJ最基础的交易思想建立在威廉指标 (Williams %R,简称W%R)的基础上,威廉指标分析资产的价格时,除了考虑每天的收盘价以外,还有综合分析资产从开市到收市期间价格的变化情况。威廉指标的计算首先选择一个时间跨度(比如14日),然后找出这一特定区间的最高价和最低价,构成一个价格变化区间;然后分析这一事件跨度最后一个时间点的收盘价与期间最高价的相对位置,再根据此相对位置来衡量市场的超买或者超卖现象。
W%R指标可以表述为:
W
%
R
=
最
近
n
天
的
最
高
价
−
第
n
天
的
收
盘
价
最
近
n
天
的
最
高
价
−
最
近
n
天
的
最
低
价
×
100
\displaystyle W\%R=\frac{最近n天的最高价-第n天的收盘价}{最近n天的最高价-最近n天的最低价}×100%
W%R=最近n天的最高价−最近n天的最低价最近n天的最高价−第n天的收盘价×100
随机指标的最早雏形是芝加哥期货交易商George Lane提出的KD指标,也称随机震荡指标。KD指标的分析思想与威廉指标类似,均使用特定时间跨度中的最后收盘价与该时间段跨度内的最高价和最低价的相对位置来推测市场的超买和超卖情况。与威廉指标不同的地方在于,随机震荡指标在收盘价与最高价和最低价的相对位置的比值上,又融入了移动平均思想,用更多的信息来捕捉市场的超买和超卖现象。
KDJ指标则是在随机震荡指标K先和D线的基础上增添1一条J线,进一步提高了随机震荡指标对市场买卖信号捕捉的周延。
KDJ指标由K线,D线,和J线三条线组成,根据特定的周期(通常为9天,9周等)内资产的最高价、最低价、最后一个计算时点的收盘价以及这三种价格的比例关系,来计算最后一个时点的未成熟随机值RSV(Raw Stochastic Value),进而通过移动平均法来计算K值、D值和J值。然后将各时点的K值,D值,J值描点连线,即得到K线,D线和J线。
计算RSV的值是求KDJ指标的第一步,RSV的计算公式为:
R
S
V
=
第
n
天
的
收
盘
价
−
最
近
n
天
内
的
最
低
价
最
近
n
天
内
的
最
高
价
−
最
近
n
天
内
的
最
低
价
×
100
\displaystyle RSV=\frac{第n天的收盘价-最近n天内的最低价}{最近n天内的最高价-最近n天内的最低价}×100
RSV=最近n天内的最高价−最近n天内的最低价第n天的收盘价−最近n天内的最低价×100
其中n为时间跨度。
也即: R S V t = C l o s e t − L o w [ t − n + 1 , t ] H i g h [ t − n + 1 , t ] − L o w [ t − n + 1 , t ] \displaystyle RSV_t =\frac{Close_t-Low_{[t-n+1,t]}}{High_[t-n+1,t]-Low[t-n+1, t]} RSVt=High[t−n+1,t]−Low[t−n+1,t]Closet−Low[t−n+1,t]
数据照常从tushare获取 平安银行股价数据
import tushare as ts import pandas as pd token = 'Your token' # 输入你的接口密匙,获取方式及相关权限见Tushare官网。这句话不能照抄! pro = ts.pro_api(token) def get_data(tscode): df = pro.daily(ts_code=tscode) df = df.loc[:, ['trade_date', 'open', 'high', 'low', 'close', 'vol']] df.rename( columns={ 'trade_date': 'Date', 'open': 'Open', 'high': 'High', 'low': 'Low', 'close': 'Close', 'vol': 'Volume'}, inplace=True) # 重定义列名,方便统一规范操作。 df['Date'] = pd.to_datetime(df['Date']) # 转换日期列的格式,便于作图 df.set_index(['Date'], inplace=True) # 将日期列作为行索引 df = df.sort_index() # 倒序以便作图 return df df = get_data('000001.SZ')
若以9日为时间跨度:
import numpy as np import matplotlib.pyplot as plt close = df.Close high = df.High low = df.Low # 获取日期数据 date = close.index.to_series() ndate = len(date) # 定义初始变量最高价High,取值均为0 periodHigh = pd.Series(np.zeros(ndate-8),index=date.index[8:]) # 定义初始变量最低价为Low,取值均为0 periodLow = pd.Series(np.zeros(ndate-8),index=date.index[8:]) # 定义初始变量RSV,取值均为0 RSV = pd.Series(np.zeros(ndate-8), index=date.index[8:]) # 计算9日未成熟随机指标RSV的值 for j in range(8,ndate): period = date[j-8:j+1] i = date[j] periodHigh[i] = high[period].max() periodLow[i] = low[period].min() RSV[i] = 100 * (close[i]-periodLow[i])/(periodHigh[i]-periodLow[i]) periodHigh.name = 'periodHigh' periodLow.high = 'periodLow' RSV.name = 'RSV'
写到这里,查看一下生成的数据:
# 对RSV作简要描述性分析 RSV.describe()
然后,我们绘制平安银行2020年数据的收盘价曲线图和RSV曲线图
# 提取数据 C_RSV=pd.DataFrame([close['2020'],RSV['2020']]).transpose()
# 绘图 plt.rcParams['font.sans-serif'] = ['SimHei'] C_RSV.plot(subplots=True, title='未成熟随机指标RSV')
RSV的取值在0~100之间,且波动范围较大。且有很多时候RSV取值接近或等于0或者100。
接下来,再绘制其K线图进一步对照:
import mplfinance as mpf s = mpf.make_mpf_style(base_mpf_style='blueskies', rc={'font.family': 'SimHei'}) add_plot=[mpf.make_addplot(RSV['2020'])] mpf.plot(df['2020'],type='candle', style=s, title='平安银行2020年K线图及未成熟随机指标RSV', addplot=add_plot,volume=True)
图像效果如下:
分析图像可知,处于上涨行情时,蜡烛图的上影线较短或者没有上影线,在部分交易日中收盘价接近或等于最高价。
由RSV计算公式和n=9可推知,若收盘价等于9日最高价,RSV取值则为100。
在下跌行情时,蜡烛图的下影线较短或者几乎没有,收盘价很有可能等于9日最低价,当收盘价接近或等于等于9日最低价的时候,RSV取值接近或为0。
当市场处于连续上涨行期的时候,未成熟随机指标RSV取值也逐渐增大,并且可能在较多日期中取值为100;当市场处于连续下跌行期的时候,RSV取值可能在较多行期中取值为0。
当RSV连续多期取值为0或100的时候,RSV则会出现所谓“钝化”的现象。
例如当收盘价在上涨行情高位变化的时候,RSV一段时间的取值均为100,不随收盘价的变化而波动,则失去了捕捉收盘价变化的作用。
需要注意的是,RSV的波动幅度较大,也可能会造成“假信号”。一种可能的情况是,在上涨行期中收盘价上涨幅度稍微增大,则可能造成RSV取值过大,进而释放出“超买”行期的假信号。
为了解决RSV波动幅度较大的问题,我们引入K指标。它是对RSV值进行平滑得到的结果。
K值由前一日的K值和当期RSV值经过一定权重调整后相加得到,一般来说,K值的计算为:
K 值 = 2 3 × 前 一 日 K 值 + 1 3 × 当 日 R S V \displaystyle K值=\frac{2}{3}×前一日K值+\frac{1}{3}×当日RSV K值=32×前一日K值+31×当日RSV
即
K
t
=
2
3
×
K
t
−
1
+
1
3
×
R
S
V
t
\displaystyle K_t=\frac{2}{3}×K_{t-1}+\frac{1}{3}×RSV_t
Kt=32×Kt−1+31×RSVt
D值是由前一日的D值和当期K值经过一定权重相加而得到。一般来说,D值的计算为:
D 值 = 2 3 × 前 一 日 D 值 + 1 3 × 当 日 K 值 \displaystyle D值=\frac{2}{3}×前一日D值+\frac{1}{3}×当日K值 D值=32×前一日D值+31×当日K值
即 D t = 2 3 × D t − 1 + 1 3 × K t \displaystyle D_t=\frac{2}{3}×D_{t-1}+\frac{1}{3}×K_t Dt=32×Dt−1+31×Kt
此外,在计算第一期K和D值时,如果没有指定,则K值和D值都默认取值为50。在K值和D值的求解过程中,平滑权重2/3和1/3是较为常用的权重,这两个权重也可以根据股价走势的特点进行适当修改。
(通过递归和迭代,我们可以发现K值是由未成熟随机指标RSV通过指数移动平均而得到的。D值是K值的指数移动平均数。)
# 计算K值 KValue = pd.Series(0.0, index=RSV.index) KValue[0] = 50 for i in range(1,len(RSV)): KValue[i] = 2/3*KValue[i-1] + RSV[i]/3 KValue.name = 'KValue' # 接着计算D值 DValue = pd.Series(0.0, index=RSV.index) DValue[0] = 50 for i in range(1, len(RSV)): DValue[i] = 2/3*DValue[i-1] + KValue[i]/3 DValue.name = 'DValue' KValue = KValue[1:] DValue = DValue[1:]
然后,绘制曲线图
plt.rcParams['font.sans-serif'] = ['SimHei'] plt.subplot(211) plt.title('2020年平安银行收盘价') plt.plot(close['2020']) plt.subplot(212) plt.title('2020年平安银行RSV与KD线') plt.plot(RSV['2020']) plt.plot(KValue['2020'],linestyle='dashed') plt.plot(DValue['2020'],linestyle='-.')
图像效果如下:
如图可以看出RSV曲线波动最大,K线在RSV基础上进行适当平滑,而D线波动幅度最小。收盘曲线上涨时,RSV曲线、KD线也呈上涨趋势;当收盘价在高位段上涨时,RSV曲线,K值,D值取值也较高,并在较高位处波动。
J指标是KD指标的辅助指标,进一步反映了K指标与D指标的乖离程度。第t日J值的计算公式为:
J t = 3 × K t − 2 × D t \displaystyle J_t=3×K_t-2×D_t Jt=3×Kt−2×Dt
# 计算J值 JValue = 3*KValue - 2*DValue JValue.name='JValue'
plt.rcParams['font.sans-serif'] = ['SimHei'] plt.subplot(211) plt.title('2020年平安银行收盘价') plt.plot(close['2020'],label='Close') plt.legend(loc='upper left') plt.subplot(212) plt.title('2020年平安银行RSV与KDJ线') plt.plot(RSV['2020'],label='RSV') plt.plot(KValue['2020'],linestyle='dashed',label='KValue') plt.plot(DValue['2020'],linestyle='-.',label='DValue') plt.plot(JValue['2020'],linestyle='--',label='JValue') plt.legend(loc='upper left')
图像效果如下:
总结随机指标KDJ的思想,首先计算最高价,最低价和收盘价之间的比例关系,再运用平滑和乖离的思想,来捕捉动量及超买、超卖等现象,在实务上对快捷直观地研判行情很有助益。