ゴールデンクロスとデットクロスで売買したらどうなるか検証してみた

シミュレーション

テクニカル分析の移動平均を用いてトレンドの分析を行います。どのように分析を進めれば良いかをチャットGPTに聞いてみましょう。

1. 移動平均の種類を選択する

  • 単純移動平均(SMA): 選択した期間にわたる価格の算術平均。例えば、20日間のSMAは過去20日間の終値の平均です。
  • 指数移動平均(EMA): 最近の価格により大きな重みを置くことで、価格の変動に対してより敏感に反応します。

2. 分析に使用する期間を決定する

  • 短期間(例:5日、10日)、中期間(例:50日)、長期間(例:200日)の移動平均を設定します。
  • 短期間のMAは価格の変動に敏感で、長期間のMAはトレンドの方向性を示します。

3. 移動平均の計算

  • SMAの計算例: 20日SMAの場合、過去20日間の終値を合計し、20で割ります。
  • EMAの計算: EMAはより複雑で、最新の価格に重みを加えて計算します。EMAの計算には、前日のEMA値も使用します。

4. 移動平均をチャートに描画する

  • 為替レートのチャートに移動平均を重ねて描画します。
  • 複数の移動平均(例:短期間と長期間)を同時に描画して、交差点やトレンドの変化を観察します。

5. 移動平均を使用したトレード戦略

  • ゴールデンクロス: 短期MAが長期MAを上から下へ突き抜けた時、買いシグナルと見なします。
  • デッドクロス: 短期MAが長期MAを下から上へ突き抜けた時、売りシグナルと見なします。
  • 価格が特定のMAを上回っている場合、強気のトレンドと見なし、MAを下回っている場合は弱気のトレンドと見なします。

データを取得する

分析を行う前にデータを取得する必要があります。Pythonのyfinanceとpandas_datareaderライブラリを用いて為替データを取得します。コードはGoogle colabにそのまま貼り付けると動作するはずです。Google colabの使い方は以下のブログを参照して下さい。

まずはライブラリのimportと為替データを取り込みます。期間は移動平均を長期間のトレンドも見れるように10年としました。時々、yahoo(US)のAPIが変わるようで取得できなることもありますができるだけ追随していきたいと思います。

import yfinance as yf
import pandas_datareader.data as pdr
import pandas as pd
import datetime

ticker = "USDJPY=X"
start = datetime.date(2013,1,1)
end = datetime.date(2023,12,31)
yf.pdr_override()
df = pdr.get_data_yahoo(ticker, start, end)

データが取得できているか確認します。

df.head()

次に取得したデータをGoogle Driveに保存できるようにします。Google colabは一定期間のアクセスがないと保存したファイルは削除されます。再度、取得すれば良いですが何回も同じデータを取得するのは取得先のサーバーへも負荷をかけますので1回取得したデータは保存しておきましょう。

from google.colab import drive
drive.mount('/content/drive')

保存するデータはcsvに変換して保存することもできますが、あとでdataframeのまま利用するのでdataframeオブジェクトのpickleファイルとして保存します。

path = '/content/drive/My Drive/data/USDJPY_2013_2023.pkl'
df.to_pickle(path)

ちなみに読み込みも簡単なので下記に示します。Google colabがタイムアウトしたり、翌日から続きを行いたい時にはここからスタートします。

path = '/content/drive/My Drive/data/USDJPY_2013_2023.pkl'
df = pd.read_pickle(path)

ここまででデータの取得が完了できました。

単純移動平均のグラフを描く

Pythonのmatplotlibライブラリを使用すると移動平均の計算からグラフの描画まで非常に簡単に行えます。

まず、どのようなデータが取得できているのかを確認します。

df.head()

次にmatplotlibライブラリとjapanize_matplotlibライブラリをインポートします。japanize_matplotlibはグラフに日本語を表示させるために必要となります。Google colabにも標準ではないため次のコマンドを入力してインストールします。

!pip install japanize-matplotlib

少し時間がかかりますが、インストールが完了すると早速次のようなコードを書いてグラフを表示させてみましょう。

import matplotlib.pyplot as plt
import japanize_matplotlib

df["Close"].plot()

Pandasのrolling関数を用いて移動平均を計算します。windowに移動平均を取りたい日数を設定します。

df['MA25'] = df['Close'].rolling(window=25).mean() # 25日移動平均
df['MA75'] = df['Close'].rolling(window=75).mean() # 75日移動平均
df['MA200'] = df['Close'].rolling(window=200).mean() # 200日移動平均
df.tail()

pandasのDataFrameに追加されていることが確認できたら、グラフにしてみましょう。

# グラフを描画
plt.figure(figsize=(14, 7)) # グラフのサイズ
plt.plot(df.index, df['Close'], label='rate')
plt.plot(df.index, df['MA25'], label='25 Day MA') # 25日移動平均
plt.plot(df.index, df['MA75'], label='75 Day MA') # 75日移動平均
plt.plot(df.index, df['MA200'], label='200 Day MA') # 200日移動平均

plt.title('USD-JPYレート 移動平均') # タイトル
plt.xlabel('Date') # X軸のラベル
plt.ylabel('Rate') # Y軸のラベル
plt.legend() # 凡例を表示
plt.show()

ゴールデンクロスとデッドクロスを追加

これでゴールデンクロスとデッドクロスの点を見つける準備ができました。25日移動平均線が75日移動平均線を下から突き抜けるゴールデンクロスと25日移動平均線が75日移動平均線を上から突き抜けるデッドクロスを計算してグラフにプロットします。

# ゴールデンクロスとデッドクロスを特定
crosses = pd.DataFrame(index=df.index)
crosses['Golden'] = (df['MA25'] > df['MA75']) & (df['MA25'].shift(1) < df['MA75'].shift(1))
crosses['Dead'] = (df['MA25'] < df['MA75']) & (df['MA25'].shift(1) > df['MA75'].shift(1))

# グラフを描画
plt.figure(figsize=(14, 7))
plt.plot(df.index, df['Close'], label='rate')
plt.plot(df.index, df['MA25'], label='25 Day MA')
plt.plot(df.index, df['MA75'], label='75 Day MA')

# ゴールデンクロスとデッドクロスの点をプロット
plt.scatter(crosses.index[crosses['Golden']], df['MA25'][crosses['Golden']], color='gold', label='Golden Cross', marker='^', s=100)
plt.scatter(crosses.index[crosses['Dead']], df['MA25'][crosses['Dead']], color='red', label='Dead Cross', marker='v', s=100)

plt.title('ゴールデン/デッドクロス')
plt.xlabel('Date')
plt.ylabel('rate')
plt.legend()
plt.show()

ちょっと10年間にすると見にくいので2016年から2018年に絞り込んで見てみましょう。

下から突き抜けるゴールデンクロスと上から突き抜けるデッドクロスがよくわかります。

売買シミュレーション

それでは最後にゴールデンクロスの時に1万円分のドルを購入して、デッドクロスで売却するを10年間繰り返すといくらになっているかを計算してみましょう。

# ゴールデンクロスとデッドクロスのポイントを特定
df['Position'] = 0  # 保有状況の列を追加(0: 保有なし, 1: 保有中)
df.loc[df['MA25'] > df['MA75'], 'Position'] = 1
df['Position'] = df['Position'].shift(1)  # 取引は次の日に行われる

# 投資リターンの計算
initial_investment = 10000
df['Change'] = df['Position'].diff()

# 購入と売却のタイミングを特定
buy = df[df['Change'] == 1]
sell = df[df['Change'] == -1]

# 投資リターンの計算
investment_jpy = initial_investment
for b, s in zip(buy.index, sell.index):
    buy_rate = df.at[b, 'Close']
    sell_rate = df.at[s, 'Close']
    investment_jpy = investment_jpy / buy_rate * sell_rate

print(f'最終的な合計額: {investment_jpy:,.0f} 円')

最終的な合計額:14,836円

となりました。日単位ではなかなかゴールデンクロスやデッドクロスが発生しないので長期的な投資となってしまいます。

10年の年平均利回りを計算しておきましょう。4.84%ですね。悪くはないですが、日経平均のインデックスでは8%だったので見劣りします。移動平均だけのテクニカル分析では限界があるので他の分析も組み合わせてみましょう。

コメント