La dernière fois, j'ai écrit sur STC (Stocastic Oscilator) en guise d'introduction à Systre. Cette fois, je voudrais reproduire MACD (Moving Average Convergence Divergence), qui est plus précis (le signal de trading sort plus rapidement) en Python, et faire une décomposition pour faire un jugement facile à comprendre. Vous obtiendrez un graphique comme celui ci-dessous.
【référence】 ① Qu'est-ce que MACD? Système évolutif de ligne moyenne mobile où les signaux de trading apparaissent tôt!? ② Comparaison du code de moyenne mobile exponentielle (EMA) écrit en Python ③ Moyenne mobile @wikipedia
・ J'ai essayé d'en faire une évolution de Stocastic Oscilator ・ À propos de l'EMA qui apparaît dans le calcul de MACD ・ Explication du code MACD
La dernière fois, même si c'était facile à voir après l'introduction de Decompose, j'ai émis un jugement en lisant le graphique ci-dessous. Ici, tout en jugeant que 20% ou moins est survendu et 80% ou plus est suracheté, le point de changement où la ligne bleue apparaît est le signe d'achat, et inversement lorsque la ligne orange apparaît. Juges comme signe de vente. Afin de juger cela systématiquement, afin d'inclure ces éléments de 20% et 80%, (% K-% D) /% K peut être calculé et jugé par la fonction suivante.
def calc_dff(dK,dD):
dff= dK.copy()
for j in range(len(dK)):
#print(j)
if dK[j]-dD[j]>0:
dff[j]=100*(dK[j]-dD[j])/(abs(dK[j])+1)
else:
dff[j]=100*(dK[j]-dD[j])/(100-abs(dK[j])+1)
return dff
Le calcul avec cette fonction donne le graphique inférieur suivant. En regardant ce graphique, le signal est plus supprimé et le moment de vendre et d'acheter est clair. Cela semble être la limite d'une moyenne mobile simple normale. Par conséquent, le graphique ci-dessus montre:
Trend=Observed-Cycle
SMA sur 5 jours (moyenne mobile simple), SMA sur 25 jours
Signal d'achat / vente = 100*(5 jours SMA-25 jours SMA)/5 jours SMA
Écrivons à propos de l'EMA (moyenne mobile exponentielle). La définition est la suivante, comme indiqué dans la référence ③ La formule de calcul de l'EMA lorsque t ≧ 3 est la suivante.
S_{{t}}=\alpha \times Y_{{t-1}}+(1-\alpha )\times S_{{t-1}}
Ici, $ S_ {{t}} $ est l'EMA à un certain moment t, et $ Y_ {{t-1}} $ est la valeur observée à un certain moment t sur la série temporelle. De plus, environ $ \ alpha = {2 \ over {N + 1}} $. L'utilisation de cet EMA, MACD, etc.
MACD = EMA de 12 jours-EMA de 26 jours
Signal = MACD EMA 9 jours
Histogramme = Signal-MACD
Par conséquent, par rapport à l'oscillateur stocastique ci-dessus, on peut considérer que la moyenne mobile simple est remplacée par la moyenne mobile exponentielle et que le nombre de jours de la moyenne mobile à long et à court terme est légèrement modifié. L'histogramme correspond au graphique du bas ci-dessus.
Je pense que le code suivant est le résultat final de ce système. J'expliquerai celui facile à comprendre en utilisant le code de Référence ②.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
from pandas_datareader import data
import statsmodels.api as sm
from statsmodels.tsa.seasonal import STL
Voici la fonction d'acquisition de données.
def get_stock(stock,start,end):
df = data.DataReader(stock, 'stooq',start)["Close"]
df = df.iloc[::-1]
return df[start:end]
Réglez les paramètres.
stock0 = '9437'
stock = stock0 + '.JP'
bunseki = "series"
start = dt.date(2020,1,1)
end = dt.date(2020,6,5)
df = pd.DataFrame(get_stock(stock, start, end))
series=df['Close']
cycle, trend = sm.tsa.filters.hpfilter(series, 144)
df['Close']=trend
Stockez les données dans la liste avec df ['Close'] .values.tolist ().
gwalk = df['Close'].values.tolist()
print(gwalk[0:3])
Des données telles que «[2978.67, 3016.01, 2972.77]» sont sorties. Calculez l'EMA sur n jours ci-dessous. Dans la référence (2), a a été fixé à 0,15, mais ici il est important de calculer a.
def EMA1(x, n):
a= 2/(n+1)
return pd.Series(x).ewm(alpha=a).mean()
Avec la fonction ci-dessus, l'EMA de 12 jours, etc. peut être facilement calculée. De plus, MACD et Signal peuvent être facilement calculés comme suit.
y12 = EMA1(gwalk, 12)
y26 = EMA1(gwalk, 26)
MACD = y12 -y26
signal = EMA1(MACD, 9)
hist_=MACD-signal
Ici, l'axe horizontal est représenté par une chaîne numérique. Vous pouvez le décrire explicitement comme l'axe horizontal du graphique, mais ce n'est pas nécessaire ici. Tout ce que vous avez à faire est de dessiner un graphique. Pour le moment, ax2.bar (ind, hist_) est un endroit gênant.
ind = np.arange(len(signal))
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 12, 4*2),dpi=200)
ax1.plot(gwalk,label="series")
ax1.plot(y12,label="y12")
ax1.plot(y26,label="y26")
ax2.plot(MACD,label="MACD")
ax2.plot(signal,label="signal")
ax2.bar(ind,hist_)
ax1.legend()
ax2.legend()
ax1.grid()
ax2.grid()
plt.show()
plt.savefig("ema_.png ")
plt.close()
Le résultat est affiché comme suit. Le résultat de la décomposition est aussi simple que ci-dessous. Ce qui suit est le résultat de 9437 NTT Docomo, mais il semble bientôt être platen. En d'autres termes, qu'il y ait du bruit ou non, le fait est que la partie où l'histogramme passe du moins au plus est achetée, et inversement la partie où elle passe du plus au moins est vendue, donc c'est presque dans le mouvement réel. On dirait qu'il y en a. ** Il s'avère que c'est un indice efficace pour l'achat et la vente à long terme. ** ** J'expliquerai l'autre axe horizontal dessiné par date en prime.
・ J'ai essayé d'exprimer Stocastic Oscilator avec un index facile à comprendre. ・ Les indicateurs utilisant MACD semblent être efficaces pour le trading à long terme.
・ Après tout, il est si facile à comprendre que je veux l'appliquer à la soi-disant systole.
Cela ne change pas grand-chose en termes de code, mais il était très difficile de mettre l'axe horizontal à la date, je vais donc l'afficher. Je pense que vous pouvez en profiter si vous le lisez attentivement.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import datetime as dt
from pandas_datareader import data
import statsmodels.api as sm
from statsmodels.tsa.seasonal import STL
def get_stock(stock,start,end):
df = data.DataReader(stock, 'stooq',start)["Close"]
df = df.iloc[::-1]
return df[start:end]
from numba import jit
@jit(nopython=True)
def EMA3(x, n):
alpha = 2/(n+1)
y = np.empty_like(x)
y[0] = x[0]
for i in range(1,len(x)):
y[i] = alpha*x[i] + (1-alpha)*y[i-1]
return y
def EMA1(x, n):
a= 2/(n+1)
return pd.Series(x).ewm(alpha=a).mean()
def calc_dff(dK,dD):
dff= dK.copy()
for j in range(len(dK)):
dff[j]=100*(dK[j]-dD[j])/(abs(dK[j])+abs(dD[j])+1)
return dff
stock0 = '9437'
stock = stock0 + '.JP'
start = dt.date(2020,1,1)
end = dt.date(2020,6,5)
df = pd.DataFrame(get_stock(stock, start, end))
date_df=df['Close'].index.tolist() #C'est le point
print(date_df[0:30])
series = df['Close'].values.tolist()
bunseki = "trend" #series" #cycle" #trend
cycle, trend = sm.tsa.filters.hpfilter(series, 144)
series2 = trend
y12 = EMA3(series2, 12)
y26 = EMA3(series2, 26)
MACD = y12 -y26
signal = EMA3(MACD, 9)
hist_=MACD-signal
ind3=date_df[:]
print(len(series),len(ind3))
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 8, 4*2),dpi=200)
ax1.plot(ind3,series,label="series")
ax1.plot(ind3,series2,label="series2")
ax1.plot(ind3,y12,label="y12")
ax1.plot(ind3,y26,label="y26")
ax2.plot(ind3,MACD,label="MACD")
ax2.plot(ind3,signal,label="signal")
ax2.bar(ind3,hist_)
ax1.legend()
ax2.legend()
ax1.grid()
ax2.grid()
plt.savefig("./stock/{}/ema_decompose_%5K%25D_{}_{}now{}.png ".format(stock0,stock,bunseki,start))
plt.pause(1)
plt.close()
df['Close']=series #series" #cycle" #trend
df['series2']=series2
df['y12'] = EMA1(df['Close'], 12)
df['y26'] = EMA1(df['Close'], 26)
df['MACD'] = df['y12'] -df['y26']
df['signal'] = EMA1(df['MACD'], 9)
df['hist_']=df['MACD']-df['signal']
date_df=df['Close'].index.tolist()
print(df[0:30])
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 8, 4*2),dpi=200)
ax1.plot(df['Close'],label="series")
ax1.plot(df['series2'],label="series2")
ax1.plot(df['y12'],label="y12")
ax1.plot(df['y26'],label="y26")
ax2.plot(df['MACD'],label="MACD")
ax2.plot(df['signal'],label="signal")
ax2.bar(date_df,df['hist_'])
ax1.legend()
ax2.legend()
ax1.grid()
ax2.grid()
plt.savefig("./stock/{}/ema_df_decompose_%5K%25D_{}_{}now{}.png ".format(stock0,stock,bunseki,start))
plt.pause(1)
plt.close()
Recommended Posts