發(fā)現(xiàn)jqdata數(shù)據(jù)方便抑淫,但技術(shù)因子是收費(fèi)項(xiàng)目,就手?jǐn)]幾個(gè)常見技術(shù)指標(biāo)以備用
1- macd
def cal_ema(df, N):
a = 2/(N+1)
b = pd.DataFrame(columns = ['close'], index=df.index)
for i in range(len(df)):
if i == 0:
b.iloc[i] = df['close'].iloc[i]
else:
b.iloc[i] = a * df['close'].iloc[i] + (1-a) * b.iloc[i-1]
return b
def cal_dea(df, short_t=12, long_t=26 ,avg_t=9):
ema_short = cal_ema(df, short_t)
ema_long = cal_ema(df, long_t)
diff = ema_short - ema_long
df['dea'] = cal_ema(diff, avg_t)
return df
2- rsi相對(duì)強(qiáng)弱指標(biāo)
通過比較一段時(shí)期內(nèi)的平均收盤漲數(shù)和平均收盤跌數(shù)來分析市場(chǎng)買沽盤的意向和實(shí)力
N日RS=[A÷B]×100%
A.....N日漲幅之和
B.....N日跌幅之和
N日RSI=A/(A+B)×100
def cal_rsi(df, period=12):
if len(df)<period:
pass
else:
delta = df.diff().dropna()
u = delta * 0
d = u.copy()
u[delta > 0] = delta[delta > 0]
d[delta < 0] = -delta[delta < 0]
u[u.index[period - 1]] = np.mean(u[:period])
u = u.drop(u.index[:(period - 1)])
d[d.index[period - 1]] = np.mean(d[:period])
d = d.drop(d.index[:(period - 1)])
avgGain = u.ewm(com=period - 1, adjust=False).mean()
avgLoss = d.ewm(com=period - 1, adjust=False).mean()
rs = avgGain / avgLoss
result = 100 - 100 / (1 + rs)
return result
3-dmi動(dòng)向指標(biāo)或趨向指標(biāo)
通過分析股票價(jià)格在漲跌過程中買賣雙方力量均衡點(diǎn)的變化情況,適用中長(zhǎng)期
Step 1. 計(jì)算Directional movement (動(dòng)向變化值)
+DM:當(dāng)日最高價(jià)比昨日最高價(jià)高并且當(dāng)日最低價(jià)比昨日最低價(jià)高澡绩,即為上升動(dòng)向+DM锤灿。上升幅度為:當(dāng)日最高價(jià)減去昨日最高價(jià)第股。
-DM:當(dāng)日最高價(jià)比昨日最高價(jià)低并且當(dāng)日最低價(jià)比昨日最低價(jià)低丁稀,即為下降動(dòng)向-DM吼拥。下降幅度為:昨日最低價(jià)減去今日最低價(jià)。
Step 2 . 計(jì)算True Range (真實(shí)波幅)
TR =∣最高價(jià)-最低價(jià)∣二驰,∣最高價(jià)-昨收∣扔罪,∣昨收-最低價(jià)∣ 三者之中的最高值
Step 3: 計(jì)算Directional Movment Index (動(dòng)向指數(shù))
+DI(14) = +DM(14)/TR(14)*100
-DI(14) = -DM(14)/TR(14)*100
Step 4: 計(jì)算ADX
DX是+DI與-DI兩者之差的絕對(duì)值除以兩者之和的百分?jǐn)?shù)秉沼。
DX=[(+DI14)-(-DI14)]/[(+DI14)+(-DI14)]*100
ADX是DX的14天平滑平均線桶雀。
ADX = SMA(DX, 14)
def cal_adx(df, N=14, M=6):
hd = df['high'].diff().dropna()
ld = -df['low'].diff().dropna()
dmp = pd.DataFrame({'dmp':[0]*len(hd)},index=hd.index)
dmp[(hd>0) & (ld<0)] = hd
dmp = dmp.rolling(N).sum().dropna()
dmm = pd.DataFrame({'dmm':[0]*len(ld)},index=ld.index)
dmm[(hd<0)&(ld>0)] = ld
dmm = dmm.rolling(N).sum().dropna()
temp = pd.concat([df['high']-df['low'], abs(df['high']-df['close'].shift(1)),\
abs(df['low']-df['close'].shift(1))],axis=1).dropna()
tr = temp.max(axis=1).dropna()
s_index = dmm.index & tr.index &dmp.index
dmp = dmp.loc[s_index]
dmm = dmm.loc[s_index]
tr =tr.loc[s_index]
pdi = 100*dmp['dmp']/tr
mdi = dmm['dmm']*100/tr
dx = abs(pdi-mdi)/(pdi+mdi)*100
adx = dx.rolling(M).mean().dropna()
adx = pd.DataFrame(adx,columns=['adx'])
return adx
4-kdj
def cal_kdj(df, N=9, M=3):
df['l_low'] = df['low'].rolling(N).min()
df['h_high'] = df['high'].rolling(N).max()
df['rsv'] = (df['close']-df['l_low'])/(df['h_high']-df['l_low'])
df['k'] = df['rsv'].ewm(adjust=False, alpha=1/M).mean()
df['d'] = df['k'].ewm(adjust=False, alpha=1/M).mean()
df['j'] = 3*df['k']-2*df['d']
return df['j']
看到有個(gè)賦值用np.where寫的,覺得挺好唬复,收藏備用
data['pre_j']=data['j'].shift(1)
data['long_signal']=np.where((data['pre_j']<lower)&(data['j']>=lower),1,0)
data['short_signal']=np.where((data['pre_j']>upper)&(data['j']<=upper),-1,0)