NASDAQ100指数から月足MACD、ゴールデンクロスを計算

勉強

前回、レバレッジ付きNASDAQ100をシミュレーション、で記載した通り、レバレッジ付きNASDAQ100を月足MACDのゴールデンクロスで売買すれば儲かるという話を聞いたので、実際に計算してみます!

再び同動画を引用していますが、私とこちらの動画の方に一切関係はありません。この方すごく丁寧でいい方だなと動画から感じています。

さっそくですが、計算結果は以下になります!

いいかんじですね!各種証券口座で確認できるMACDと似たようなグラフを出力できました。

では、月足MACDの計算、シグナル(ゴールデンクロス、デッドクロス)の計算を行っていきます!

今回の計算に当たって、MACDの計算式やシグナルについての詳細はこちらを参考にさせていただきました!

単純移動平均・指数平滑移動平均線

MACDの計算は少し複雑で、株価から計算される二つの平均値を使って計算されます。


一つはn日単純移動平均線(nSMA)で、n日分の価格の平均値になります。移動平均といえば、コロナ感染者数の指標として単純移動平均線(SMA)が使われていましたね。ここで、i日目の価格をViとしています。

$$\mathrm{nSMA}=\frac{1}{n}\Sigma_{i=1}^{n}V_i$$

もう一つがn日指数平滑移動平均線(nEMA)です。こちらはn日分の価格の新しい価格の比重を大きくして計算された数値になります。k日目のnEMAは

$$\mathrm{nEMA}_k=\frac{2}{n+1}V_i+\mathrm{nEMA}_{k-1} \\
\mathrm{nEMA}_n=\frac{1}{n}\Sigma_{i=1}^{n}V_i$$

で計算できます。どちらの平均も、n日分のデータが必要になるのでn-1番目の数値を計算することはできません。

通例として、これらの平均値は短期は12日分、長期は26日分を使うことが多いみたいです。

とりあえずPythonで実装してみましょう!計算結果はこちら。

オレンジと緑が指数平滑移動平均線の短期と長期で、赤と紫が単純移動平均線の短期と長期になります。短期が常に長期を上回っているところから、NASDAQ100指数の強さがわかりますね。また、確かにEMAの方がSMAより株価の変化に素早く対応しているように見えますね。

こちらを計算したPythonプログラムはこちら

import pandas_datareader as web
import matplotlib.pyplot as plt

start='2000-10-18'
end='2022-05-20'

# NASDAQ100の一日毎の終値を取得
df_nasdaq100 = web.DataReader(data_source='yahoo', name='^NDX',start=start,end=end) 

# 1日毎のデータをひと月辺りのデータに
df_nasdaq100_Month=round(df_nasdaq100['Close'].resample(rule="M").mean())
# EMAを計算
df_nasdaq100_12EMA=df_nasdaq100_Month.ewm(span = 12, min_periods = 12).mean()
df_nasdaq100_26EMA=df_nasdaq100_Month.ewm(span = 26, min_periods = 26).mean()
df_nasdaq100_12SMA=df_nasdaq100_Month.rolling(window=12).mean()
df_nasdaq100_26SMA=df_nasdaq100_Month.rolling(window=26).mean()

# データをプロット
plt.plot(df_nasdaq100_Month)
plt.plot(df_nasdaq100_12EMA, label='12EMA')
plt.plot(df_nasdaq100_26EMA, label='26EMA')
plt.plot(df_nasdaq100_12SMA, label='12SMA')
plt.plot(df_nasdaq100_26SMA, label='26SMA')
plt.xlabel('date')
plt.ylabel('value')
plt.legend()
plt.show()

pandasのデータフレームにある関数を使うことでとっても簡単に計算できました!

月足MACD

長かったですが、ようやくMACDの計算です。MACD(Moving Average (移動平均) Convergence (収束) Divergence(発散))とは株価の移動平均の短期と長期平均価格の一致具合に関する指標ですね。

MACDは以下で定義されるMACD線、シグナル、ヒストグラムからなるようです。

$$\mathrm{MACD}=\mathrm{12EMA} – \mathrm{26EMA}\\
\mathrm{Signal} = \mathrm{9SMA(MACD)} \\
\mathrm{Hist} = \mathrm{MACD}-\mathrm{Signal}$$

これを実装するのは簡単ですね!計算してみました!

いいかんじですね!こちらは以下のPythonプログラムで計算されました。

import pandas_datareader as web
import matplotlib.pyplot as plt
import numpy as np

start='2010-10-18'
end='2022-05-20'

# NASDAQ100の一日毎の終値を取得
df_nasdaq100 = web.DataReader(data_source='yahoo', name='^NDX',start=start,end=end) 

# 1日毎のデータをひと月辺りのデータに
df_nasdaq100_Month=round(df_nasdaq100['Close'].resample(rule="M").mean())
# EMAを計算
df_nasdaq100_12EMA=df_nasdaq100_Month.ewm(span = 12, min_periods = 12).mean()
df_nasdaq100_26EMA=df_nasdaq100_Month.ewm(span = 26, min_periods = 26).mean()

# MACDとSignalの計算
MACD = df_nasdaq100_Month.ewm(span = 12, min_periods = 12).mean()[25:]-df_nasdaq100_Month.ewm(span = 26, min_periods = 26).mean()[25:]
Signal=MACD.rolling(window=9).mean()
Hist=MACD[8:]-np.array(Signal[8:])

# 各種データをプロット
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
ax1.plot(df_nasdaq100_Month[25:])
ax1.plot(df_nasdaq100_12EMA[25:], label='12EMA')
ax1.plot(df_nasdaq100_26EMA[25:], label='26EMA')
ax2.plot(MACD[8:], label='MACD')
ax2.plot(Signal[8:], label='9SMA')
# シグナルの正負とクロス位置が分かりやすいように各種色を付ける
color_Signal = [('b' if i > 0 else 'r') for i in (MACD[8:]-np.array(Signal[8:]))]
ax2.bar(Hist.index, Hist*2,width=1,color=color_Signal)
ax1.legend()
ax2.legend()
plt.show()

ゴールデンクロス、デッドクロス

で、NASDAQ100を購入するタイミングはSignalとMACDがクロスする点、またはヒストグラムが反転するところになります!

MACDがSignalを抜いた点をゴールデンクロス(買い時)で、その逆をデッドクロス(売り時)と呼ぶそうです。上記のプログラムにこれらの点を付け加えたものがこちら!

買い時と売り時がわかりやすいですね!以上のプログラムはこちらになります。

import pandas_datareader as web
import matplotlib.pyplot as plt
import numpy as np

start='2010-10-18'
end='2022-05-20'

# NASDAQ100の一日毎の終値を取得
df_nasdaq100 = web.DataReader(data_source='yahoo', name='^NDX',start=start,end=end) 

# 1日毎のデータをひと月辺りのデータに
df_nasdaq100_Month=round(df_nasdaq100['Close'].resample(rule="M").mean())
# EMAを計算
df_nasdaq100_12EMA=df_nasdaq100_Month.ewm(span = 12, min_periods = 12).mean()
df_nasdaq100_26EMA=df_nasdaq100_Month.ewm(span = 26, min_periods = 26).mean()

# MACDとSignalの計算
MACD = df_nasdaq100_Month.ewm(span = 12, min_periods = 12).mean()[25:]-df_nasdaq100_Month.ewm(span = 26, min_periods = 26).mean()[25:]
Signal=MACD.rolling(window=9).mean()
Hist=MACD[8:]-np.array(Signal[8:])

# クロスの判定(ここは自作)
Cross=[]
for i in range(1,len(Hist.index)):
    if np.sign(Hist[i]) != np.sign(Hist[i-1]):
        Cross.append(MACD[i+7])
    else:
        Cross.append(0)        

# 各種データをプロット
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
ax1.plot(df_nasdaq100_Month[25:])
ax1.plot(df_nasdaq100_12EMA[25:], label='12EMA')
ax1.plot(df_nasdaq100_26EMA[25:], label='26EMA')
ax2.plot(MACD[8:], label='MACD')
ax2.plot(Signal[8:], label='Signal')
# シグナルの正負とクロス位置が分かりやすいように各種色を付ける
color_Signal = [('b' if i > 0 else 'r') for i in (MACD[8:]-np.array(Signal[8:]))]
color_Cross = [('w' if i == 0 else 'r') for i in (Cross)]
ax2.bar(Hist.index, Hist*2,width=1,color=color_Signal)
ax2.scatter(Hist.index[:-1],np.array(Cross),color=color_Cross)
ax1.legend()
ax2.legend()
plt.show()

これで月足MACDとゴールデンクロス、デッドクロスを完璧に理解できましたね!
もちろん各種証券会社のチャートツールでこれを表示できますが、車輪の再開発は楽しいものです。

あとは、while分で毎日シグナルを観測するようにし、こちらに従ってGmailにメールを送る設定とかすれば、シグナルが発生するたびにメールで確認できるようになりますね!

皆様の参考になればと思います。よければコメントいただけるとありがたいです。

コメント

タイトルとURLをコピーしました