我在网上查了好久都没有找到容易理解的DMI(动向指数)代码,所以自己写了一个,但绘制出来的图与东方财富显示的有些不同。我查了很久也没发现 bug,先放在这里,日后有机会再修改。
def DMI(self):
self.data['yclose'] = self.data['Close'].shift(1)
self.data['yopen'] = self.data['Open'].shift(1)
self.data['yhigh'] = self.data['High'].shift(1)
self.data['ylow'] = self.data['Low'].shift(1)
TR=[]
pdi=[]
ndi=[]
for index,row in self.data.iterrows():
listt = [self.data.loc[index,'Close'], self.data.loc[index,'Open'],
self.data.loc[index,'High'], self.data.loc[index,'Low']]
listy=[self.data.loc[index,'yclose'], self.data.loc[index,'yopen'],
self.data.loc[index,'yhigh'], self.data.loc[index,'ylow']]
DM_p, DM_n = 0, 0
if self.data.loc[index,'Close']==self.data.loc[index, 'Limit_up']:
DM_p = self.data.loc[index, 'Close'] - max(listy)
if self.data.loc[index, 'Close'] == self.data.loc[index, 'Limit_down']:
DM_p = min(listy)-self.data.loc[index, 'Close']
if max(listt)>max(listy)and min(listt)>min(listy):
DM_p=max(listt)-max(listy)
if max(listt)<max(listy)and min(listt)<min(listy):
DM_n=abs(min(listt)-min(listy))
if max(listt)<max(listy)and min(listt)>min(listy):
DM_p, DM_n = 0, 0
else:
if max(listt) - max(listy) == min(listy) - min(listt):
DM_p, DM_n = 0, 0
if max(listt)-max(listy)> min(listy)-min(listt):
DM_p=max(listt)-max(listy)
else:
DM_n=min(listy)-min(listt)
DM_p, DM_n = abs(DM_p),abs(DM_n)
# TR
a = abs(max(listt) - min(listt))
b = abs(max(listt) - self.data.loc[index,'yclose'])
c = abs(min(listt) -self.data.loc[index,'yclose'])
TR_list = [a, b, c]
tr = max(TR_list)
TR.append(tr)
pdi.append((DM_p / tr)*100)
ndi.append((DM_n / tr)*100)
add = pd.DataFrame({'TR': TR,'+DI': pdi,'-DI': ndi})
# 合并时将 add DataFrame 的索引设置为一个新的列,以备后续合并
self.data.reset_index(inplace=True)
add['Date']=self.data['Date']
# 将合并后的 DataFrame 的索引设置为 'add' DataFrame 的索引列(原先的索引)
self.data = pd.merge(self.data, add, on='Date', how='right')
self.data.set_index('Date', inplace=True)
self.data["+DI13"]=self.data['+DI'].ewm(span=13, adjust=False).mean()
self.data["-DI13"] = self.data['-DI'].ewm(span=13, adjust=False).mean()
DX=[]
for index, row in self.data.iterrows():
dx= abs(((self.data.loc[index,"+DI13"] - self.data.loc[index,"-DI13"]) /
(self.data.loc[index,"+DI13"] + self.data.loc[index,"-DI13"])) * 100)
DX.append(dx)
add=pd.DataFrame({'DX': DX})
self.data.reset_index(inplace=True)
add['Date']=self.data['Date']
# 将合并后的 DataFrame 的索引设置为 'add' DataFrame 的索引列(原先的索引)
self.data = pd.merge(self.data, add, on='Date', how='right')
self.data.set_index('Date', inplace=True)
self.data["ADX"] = self.data['DX'].ewm(span=13, adjust=False).mean()
return self.data