def getKDJ(close, high, low):
'''
calculate KDJ value
:param DataFrame close:close price
:param DataFrame high:highest price of a day
:param DataFrame low: lowest price of a day
:return: [DataFrame,DataFrame,DataFrame,DataFrame] [RSV, K, D, KDJ]:KDJ value and some subproducts
'''
# interval over which KDJ is calculated
kdj_interval = 9
N = 3
# calculate RSV
# get the close value to be used
close = pd.DataFrame(close.iloc[(kdj_interval - 1):, :].values)
# calculate maximum in (kdj_interval) days in high value
high_max_in_interval = pd.rolling_max(high, kdj_interval)
# rolling_sum function will set the first (kdj_interval-1) days as np.nan,drop them
high_max_in_interval.dropna(inplace=True)
# set index with 0,1,2...,otherwise it will be kdj_interval,kdj_interval+1,...(may not be explicit but fuck the index)
high_max_in_interval.index = range(high_max_in_interval.shape[0])
low_min_in_interval = pd.rolling_min(low, kdj_interval)
low_min_in_interval.dropna(inplace=True)
low_min_in_interval.index = range(low_min_in_interval.shape[0])
# calculate RSV
RSV = 100 * (close - low_min_in_interval) / (high_max_in_interval - low_min_in_interval)
# replace np.nan and np.inf in RSV because there might be 0 in the denominator of the last formula
RSV.replace([np.nan, np.inf,-np.inf], 0, inplace=True)
# get matrix shape
[row, col] = RSV.shape
# calculate K
# assuming N equals n in the formula
# initialize both N and K with 50
K = pd.DataFrame(np.zeros([row, col]))
D = pd.DataFrame(np.zeros([row, col]))
K.iloc[0, :] = 50 * np.ones([1, col])
D.iloc[0, :] = 50 * np.ones([1, col])
# calculate K and D iteratively
for i in range(1, row):
K.iloc[i, :] = (RSV.iloc[i, :] + K.iloc[(i - 1), :]) / N
D.iloc[i, :] = (K.iloc[i, :] - D.iloc[(i - 1), :]) / N
KDJ = 3 * K - 2 * D
return [RSV, K, D, KDJ]
评论列表
文章目录