過去50年間のS&P500の季節性の値動きから負けにくいポジション構築はできるのか考える・大統領選挙のアノマリー対応!【コピペで動く!】Google ColabのPythonで自分で調べてみよう!

スポンサーリンク
投資

Twitterで出てくる知見は本当か自分で調べてみるシリーズです。株式投資において、季節、月による特徴的な値動きや有利なポジションでの新規エントリーや手じまいなど可能なのでしょうか?Pythonによる分析で確認してみたいと思います。

また、また、株式投資をしない人でもPythonで日付取り扱いなど”実務”の視点からすぐに使える、コピペで使えるものとなっています!

記事を書こうと思ったきっかけ

以前このような4月にS&P500の上昇しやすいものを確認した記事”【アノマリー】4月は上昇しやすい【季節性】は本当か?Google ColabのPythonで自分で調べてみよう!(Python コードあり)【コピペで動く!】Twitterで出てくる知見は本当か自分で調べてみようシリーズ”という事を書いたことがあります。

4月以外にもそういったアノマリーはあるのでしょうか?

以下のようなTweetを拝見しました。

6月下旬に安値を付けて、7月は強い傾向があるようです。

また、このようなアノマリーもあるようです。

2022/07/03の段階で、素晴らしい2週間が予言されていたようです。

こうなってくると、もう調べるまでもなく7月は強いような気もします。

2022/09/01追記:開始

上記7月の強さを強調するものが以外に9月の弱さを指摘する物もあります。

2022/09/01追記:終了

まあ、何事にも例外はあるでしょうから、今後のために今回調べていきます。

あと、個人のTwitterだけでなく大手のWebではこのように見えているようです。

Seasonality | Free Charts | StockCharts.com
Charts that show the monthly price performance trends for a stock, ETF or other security over an adjustable period of time, showing seasonal trends and statisti...

平均という形ではないですが、直近の指定の年数の価格の推移が見れます。

確かに7月は強くここ5年では全勝(すべて上昇)だったようです。

使用するツール

使用するツールはGoogle Colaboratoryのpythonを使いますので、無料で、簡単に行うことができます。Google Colaboratoryについては以前書いた記事をご参照いただければと思います。

実際のコードとやっていること

今回使ったコードはGoogle Colabのファイルとして以下にシェアしてあります。

以前書いた記事”曜日による米国株指数(S&P500)のパフォーマンスに違いはあるのか?有利なポジション取りはできるのか?【Google ColabのPython:コピペで動く!】Twitterで出てくる知見は本当か自分で調べてみよう。”などを参考にしながらコーディングしていきます。

今回はhttps://charts.equityclock.com/ で”11 Year range ending 12/31/2121″での平均と出ていたので、Vanguard S&P 500 ETF (VOO)で検証確認開始を2010/01/01とすることにします。

SPDR S&P 500 Value ETF (NYSE:SPYV) Seasonal Chart | Equity Clock

実際のコードは以下の通りです。まず、最初に月ごとの上昇幅を調べます。

!pip install yfinance --upgrade --no-cache-dir

import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import datetime

start_D="2000-1-1"#@param {type:"string"}
end_D=datetime.date.today()
codelist1 = ["VOO"]

data2 = yf.download(codelist1, start=start_D, end=end_D)

display(data2.dropna().head(1).append(data2.dropna().tail(1)))
data2["Adj Close"].plot()
plt.show()

VOOについてはトレード開始したのは2010/09/09のようですので、約20年という事になります。

データがYahoo Finance USから取得できましたので、次は次ごとの成績を調べます。

この部分については以前の記事”【アノマリー】4月は上昇しやすい【季節性】は本当か?Google ColabのPythonで自分で調べてみよう!(Python コードあり)【コピペで動く!】Twitterで出てくる知見は本当か自分で調べてみようシリーズ“を参考にしながら進めます。

import pandas as pd
import datetime

analyse=100*data2["Adj Close"].pct_change().copy()

def MonthNumberToMonthName(month):
    date = datetime.date(2022, month, 1)  
    return date.strftime("%B")

analyse_SIM=pd.DataFrame()
for i in range(1,13):
  month_name = MonthNumberToMonthName(i)
  analyse_SIM[month_name]=analyse[analyse.index.month==i].groupby([lambda x: x.year]).sum()

グラフ・チャートで可視化すると以下のようになります。

display(analyse_SIM.mean())
analyse_SIM.mean().plot.bar(figsize=(10,4),fontsize=18)
plt.grid(True)
plt.axhline(y=0, linewidth=4, color='r')
plt.show()

箱ひげ図で可視化すると以下のようになります。〇は外れ値になります。こうやって見ると外れ値は下落時に出やすいのが見て取れるような気がします。7月、8月は外れ値が出にくく、平均的な値動きという事になるのでしょうか。

plt.rcParams["font.size"] = 9
fig, ax = plt.subplots(figsize=(12, 7))

ax =analyse_SIM.boxplot()

年間累積では以下のような損益曲線になります。

analyse_SIM.mean().cumsum().plot(figsize=(10,4),fontsize=18)
plt.grid(True)
plt.axhline(y=0, linewidth=4, color='r')
plt.show()

これを日にちでもう少し細かく見ていきます。

年の情報を削除し、うるう年の2/29が対応できるように2020年での日数にいったん日にちを変換します。

import datetime

df=pd.DataFrame()
df["VOO"]=pd.DataFrame(data2["Adj Close"].pct_change())
df=df.reset_index()
df["MMDD"]=df["Date"].dt.strftime('2020/%m/%d')
df["MMDD"]=pd.to_datetime(df["MMDD"])
display(df)
display(df.info())

2021/12/31までのデータと今年のデータを分けて、dataframeに変換しておきます。

df1=(df[["VOO","MMDD"]][df.Date<="2021/12/31"].copy()).set_index("MMDD")
df2=(df[["VOO","MMDD"]][df.Date>"2021/12/31"].copy()).set_index("MMDD")

df3=(df1.groupby([lambda x: x.month,lambda y: y.date]).mean()).reset_index()
df3=df3.set_index("level_1")

display(df3.tail(2))
display(df2.tail(2))

平均値のデータと今年のデータをプロットします。

import matplotlib.dates as mdates

plt.rcParams["font.size"] = 12
fig, ax = plt.subplots(figsize=(10, 5))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))

plt.plot((1+df3["VOO"]).cumprod(),label="20years average")
plt.plot((1+df2["VOO"]).cumprod(),label="This year")
plt.legend(bbox_to_anchor=(1, 0.5), fontsize=12)   

ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))

plt.grid()
plt.show()

Webサービスでの表示はこのようになっており、似たよなチャートになっていることが分かります。

2022/09/01追記:S&P500 インデックスで50年間(1971年から)確認できるようにしました。

以下のように過去50年での成績が出ていましたので、確認もかねて、ETFではなくS&P500インデックスで1970年から調べられるようにしました。

start_D="1970-1-1"
end_D=datetime.date.today()
codelist1 = ["^GSPC"] 

としてあります。参照Google Colabファイルはこの内容になっています。

結果は

でなりました。

2022/09/01追記:終了

考察

2022年の7月は非常に強かったですね。20年間の統計的にも上半期が終わって、リバランスなど買いが入りやすいのでしょうか?それとも空売りなどで儲けるタイプのヘッジファンドマネージャーが夏休みになってあまり売りが出てこないのでしょうか。

ただ、”4月は上がりやすいアノマリー”に全く反応しなかったのに、7月だけ従うと判断するのもなかなか難しかったかもしれませんし、そもそも平均値では年間で緩やかな上昇を期待する中、今年は比較的大幅な下落をする状態ですので、どこまで”アノマリー”にかけられるかという胆力が試される展開だったかもしれません。

今後ともアノマリー的な値動きはフォローアップしてみたいと思います。

最後に自動更新される最新データでのアノマリーデータと今年のデータを載せておきます。

”相場は韻を踏むのか?2007年の下落と似ているところと似ていないところ”同様自動更新されますので、興味ある方は継続して確認してみてください。

追記:大統領選挙の4年サイクルのアノマリー

以下のようなコメントをいただきました。

それほど難しくないので、ご希望にこたえて検証してみたいと思います。

まず、コーディングする前に、オフィシャルな正しい結果を確認してみたいと思います。

いくつか情報があります。https://charts.equityclock.com/ では以下のような結果があります。

Dow Jones Industrial Average Four-year Election Cycle Seasonal Charts | Equity Clock

選挙前年のチャートも下方には出ています。

また、MONEXさんの方では以下のような記事を2022/08/08に書かれているようです。

米中間選挙の年の米国株式市場のアノマリー | 岡元兵八郎の米国株マスターへの道 | マネクリ マネックス証券の投資情報とお金に役立つメディア
業績の下方修正は米国株式市場に織り込まれている。米中間選挙イヤーの7月にS&P500が上がると、8月9月も上昇する可能性が高いアノマリー

7月のアノマリーは分かりませせんが、一般的には9月まで弱そうな感じです。

それを踏まえて確認をしてみたいと思います。

実はそんなにむずくかしくないです。方針としては選挙は4年に一度なので、年を4で割ると余りが0,1,2,3になりますので、その対応する余りの年だけ取り出して、同じコードを適応すればよいだけになるはずです。

また、参照するデータ数が1/4になってしまいますのでもう少し長い期間で確認する必要があります。上記MONEXさんの記事ではデータの取得を1930年から行っていました。

前回はVOOというS&P500に対応するETFでデータ分析を行いましたが、1930年からは当然そのETFはありませんので、今回の検証ではS&P500のインデックス指数そのものを使ってみたいと思います。

修正分のコードは以下の通りです。

!pip install yfinance --upgrade --no-cache-dir

import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import datetime

start_D="1930-1-1"#@param {type:"string"}
end_D=datetime.date.today()
codelist1 = ["^GSPC"]

data2 = yf.download(codelist1, start=start_D, end=end_D)

display(data2.dropna().head(1).append(data2.dropna().tail(1)))
data2["Adj Close"].plot()
plt.show()

データ取得開始日を 1930-1-1 にしています。

取得データのコードを ^GSPC とS&P500の指数インデックスにしています。

import pandas as pd
import datetime

df_full=100*data2["Adj Close"][:"2022-1-1"].pct_change().copy()
analyse=df_full[df_full.index.year%4==2].copy()

def MonthNumberToMonthName(month):
    date = datetime.date(2022, month, 1)  
    return date.strftime("%B")

analyse_SIM=pd.DataFrame()
for i in range(1,13):
  month_name = MonthNumberToMonthName(i)
  analyse_SIM[month_name]=analyse[analyse.index.month==i].groupby([lambda x: x.year]).sum()

display(analyse_SIM.mean())
#display(analyse_SIM)

df_full=100*data2[“Adj Close”][:”2022-1-1″].pct_change().copy() analyse=df_full[df_full.index.year%4==2].copy()

分かりやすく2行に分けてみました。今回は中間選挙の年、大統領選挙の2年前という事ですので、余り2の年を抜き出しています。

結果だけ書くとこのような感じです。

月次は上記MONEXさんと似たようなものに当然なります。

また、日次の累積も以下のようになります。

ダウ平均との差がありますが、9月までの下落傾向は同じようなものが見て取れると思います。

今年との比較はこのようになるようです。

コメントありがとうございました。すべてに答えられるものではありませんが、可能なものに対しては対応させていただきたいと思います。

引き続きよろしくお願いいたします。

ディスクレーマー

投資に関する免責事項情報の提供・作業代行を目的としており、投資勧誘を目的とするものではありません。

投資に関する記事をご紹介します。

Python高速化! for文は遅いので、”これ”を使うと30倍早いですよ!【Google ColabのPython:コピペで動く!】
【コピペで動く!】Pythonで1.5GBのcsvファイル読み込み高速化:1分5秒⇒4秒程度 DASK , pickle (Pythonコードあり)
【コピペで動く!】日本株、米国株で個別銘柄ベータ値(β値)を簡単に調べる方法 Python 米国株 Webサービス&コード 【Google Colabで違いをみつけろ!】
【コピペで動く!】Google ColabでPython を用いての 効率的フロンティア と ポートフォリオの最適化 Efficient Frontier & Portfolio Optimization with Python [Part 2/2]
【コピペで動く!】20行で資産運用モデル作成 Google ColabのPythonで 米国株の株価を取得し、グラフ・チャートを表示
過去50年間のS&P500の季節性の値動きから負けにくいポジション構築はできるのか考える・大統領選挙のアノマリー対応!【コピペで動く!】Google ColabのPythonで自分で調べてみよう!
曜日による米国株指数(S&P500)のパフォーマンスに違いはあるのか?有利なポジション取りはできるのか?【Google ColabのPython:コピペで動く!】Twitterで出てくる知見は本当か自分で調べてみよう。
【解決】スクレイピングでHTTP Error 403: Forbiddenでアクセスできないときに試すべき方法【コピペで動く!】【Google Colab:Python:pd.read_html,selenium】
【解決】Google ColabのPythonでエクセル(Excel)ファイルやCSVファイルに出力・入力する方法【コピペで動く!】
【コピペで動く!】レイ・ダリオ推奨「オール・ウェザー戦略」をETFで構築するには? ETFの手軽さとそのパフォーマンスの高さとは!【違いをみつけろ!】
【コピペで動く!】IB証券(インタラクティブ・ブローカーズ証券 )へのPythonでのAPI接続 ib_insync [自分が使っているPythonコード]
米国債のゼロクーポン債STRIPSについてのメモ
自動化・効率化でなにができるのか!Google FinanceやYahoo Financeからデータ取得して年初来パフォーマンスや週次騰落率のファクターチェック
米国株のティッカー(Symbol)のスクレイピングによる取得、APIによるヒストリカルデータやファンダメンタルズデータ取得について【コピペで動く!】Python,Quandl,無料枠あり
Google ColabでYouTube動画を開始・終了の時間を指定してPythonでダウンロード(音声・動画両方対応)【コピペで動く!】

コメント