見出し画像

S&P500 今後の価格を予測する

サブテーマ:Facebook Prophetを使ってみる



1 初めに

 今回、プログラミングの真骨頂未来予測にチャレンジします。過去ARIMAXモデル等古典モデルについては紹介済です。今回は比較的最近かつ使えると評価の高いモデルの中から、prophetモデルを使った今後の予測を実施してみました。Pythonを使ってみる良い練習にもなると思いますので是非見てみてください。

今回の結論:
・S&P500”SPY”を予測
(QQQ:NASDAQ100、TLT:長期国債の価格も併せて学習)

Prophetモデルを使ったS&P500指数連動ETF”SPY”の30日間価格予測結果

知人よりプログラム部分が難しくてよくわからないとご指摘をいただきました。そのためこのチャンネルでは、PYTHONを使った米国株投資に関わるさまざまな調査の結果OUTPUTにこだわった記事にします。投資に関わる身近な疑問にも答えていきますので、投資リテラシー向上にお役立ちを目指します!!
 なお、全ての解析データは引き続き、PYTHONを活用してコード全文も掲載します。Googleコラボで動作確認したコードですので、まずは”コピペ”でチャレンジできます。これから勉強始めたい方にも、プログラミングで何ができるのかを知る良いチャンスとなればと思っていますので応援お願いします!!
(申し訳ありませんが、コード全文のみ有料設定させてもらってます。応援いただける方、時系列予測に挑戦したい方はぜひご検討ください。)


2 豆知識

1)Prophetとは

Prophetは、Facebookが開発したオープンソースの時系列データ予測ツールです。このツールは、PythonとRの両方で利用可能で、特にビジネスにおける需要予測や収益予測などに強力な機能を提供します。Prophetは、複雑な時系列データのパターンをキャプチャし、将来の値を予測するのに優れたツールです。
 Prophetの大きな特徴は、その使いやすさにあります。基本的な予測を行うには、以下のステップを踏むだけです。

  1. データの準備: 予測する時系列データを用意します。データは、日時情報を示す「ds」列と、予測対象の値を示す「y」列の2つの列で構成されます。

  2. モデルの作成: Prophetモデルを初期化します。Prophet()を呼び出すだけで、基本的なモデルが作成されます。

  3. モデルのフィット: 用意したデータをモデルにフィットさせます。これは、model.fit(data)とするだけで実行されます。

  4. 予測の実行: 予測を行うための未来の日付を含むデータフレームを作成し、model.predict(future)を呼び出して予測を実行します。

強力な機能の特徴

  • 季節性のモデリング: 年次、週次、日次の季節性を簡単にモデリングできます。また、独自の季節性を追加することも可能です。

  • 休日効果の追加: 祝日や特定のイベントによる影響をモデルに組み込むことができます。

  • 不規則なデータ対応: 欠損値や不規則な間隔のデータにも柔軟に対応できます。

  • 回帰変数の追加: 他の外部要因を考慮した回帰変数を追加することで、より精度の高い予測が可能です。

上記のような理由でProphetは、多くの業界で活用されています。例えば、小売業では季節ごとの売上予測や、マーケティングキャンペーンの効果を予測するのに使用されます。また、IT業界ではウェブサイトのトラフィック予測やシステムのパフォーマンスモニタリングにも利用されています。今回はこの機能を株価予測に使ってみた結果となります。

3 実践

1)調査内容

ProPhetをPipインストールののち、YahooFinanceから過去20年の実績を取得します。なお、実施結果の通り、S&P500のみの価格ではうまく時系列に沿った予測ができてないため、説明変数としてハイテク価格としてNASDAQ100と、金利価格を参照するため長期米国債の価格を説明変数として学習させています。
 目的変数 : S&P500インデックス連動ETF:SPY
 説明変数 : NASDAQ100(QQQ)、長期米国債ETF(TLT)
その後、モデルの入力箇所に従って入力するだけで予測を出力することができます。なお、今回20年の長期にわたるS&P500の価格を取得したため、直近30日が短すぎてよく見えないため、拡大グラフを表示させました。

2)実践① SP500(SPY)のみで学習

初めにprophetとyfinaceをPipインストールし、使用するツールを一通り読み込みます。

!pip install yfinance japanize-matplotlib prophet

import pandas as pd
import numpy as np
import yfinance as yf
from prophet import Prophet
import matplotlib.pyplot as plt
from datetime import date
import japanize_matplotlib

その後、YahooFinaceからdataとして価格を読み込み、Prophet用のデータとしてデータ準備を行います。なお今回は始値’Open’を取得しています。これは実際のアメリカETFの売買は昼間検討して、成り行きで注文出しおくとこの始値で売買することになると考えたからです。(ぜひご自身の状況にあわせClose,AdjCloseでも挑戦してみてください。)
 また価格に対し変化率で学習させると精度が上がる場合があるため、対数変換して学習させています。

# Yahoo FinanceからSPYデータを取得
end_date = date.today().strftime("%Y-%m-%d")  # 終了日は現在の日付
start_date = '2004-01-01'  # 過去のデータの開始日
data = yf.download('SPY', start=start_date, end=end_date)['Open']

# 対数変換を適用
data_log = np.log(data)

# Prophet用のデータを準備
df = data_log.reset_index()
df.rename(columns={'Date': 'ds', 'Open': 'y'}, inplace=True)

季節性の考慮は下記のコードでそれぞれTrueorFalseで指定します。
 daily_seasonality=False: 日次の季節性を無効
 yearly_seasonality=True: 年次の季節性を有効
 weekly_seasonality=False: 週次の季節性を無効
あわせて、次の行で月次の季節性を追加しています。
 name='monthly': 季節性の名前を "monthly"
 period=30.5: 月次の周期を約30.5日
 fourier_order=5: フーリエ次数を5。月次の季節性の複雑さを制御
著者が実行した設定が適切とは限りませんので、ぜひご自身でトライしてみてください。

# Prophetモデルを初期化し、追加の季節性を追加
model = Prophet(daily_seasonality=False, yearly_seasonality=True, weekly_seasonality=False)
model.add_seasonality(name='monthly', period=30.5, fourier_order=5)
model.fit(df)

次に予測ですが、下記のコードで実行できます。periods=30の日数を変更することで予測する日の変更が可能です。

# 未来のデータフレームを作成
future = model.make_future_dataframe(periods=30)  # 30日先まで予測
forecast = model.predict(future)

最後に、対数として計算していたので、元に戻しグラフに出力することで完了となります。

# 予測データの対数変換を元に戻す
forecast['yhat'] = np.exp(forecast['yhat'])
forecast['yhat_lower'] = np.exp(forecast['yhat_lower'])
forecast['yhat_upper'] = np.exp(forecast['yhat_upper'])

# 信頼区間とともに過去と予測データをプロット
plt.figure(figsize=(14, 7))

# 実際のデータをプロット
plt.plot(data.index, data, label='実際のデータ', color='black')

# 予測データをプロット
plt.plot(forecast['ds'], forecast['yhat'], label='予測', color='blue')
plt.fill_between(forecast['ds'], forecast['yhat_lower'], forecast['yhat_upper'], color='lightblue', alpha=0.5, label='信頼区間')

# ラベルとタイトル
plt.xlabel('日付')
plt.ylabel('始値')
plt.title('Facebook Prophetを用いたSPY時系列予測(対数変換)')
plt.legend()
plt.grid(True)
plt.show()

# 予測データをCSVファイルに保存
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].to_csv('SPY_forecast_log.csv', index=False)

# 予測データを表示
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(30))

# 過去のデータを含む予測データをプロット
plt.figure(figsize=(14, 7))
plt.plot(data.index, data, label='実際のデータ', color='black')
plt.plot(forecast['ds'], forecast['yhat'], label='予測', color='blue')
plt.fill_between(forecast['ds'], forecast['yhat_lower'], forecast['yhat_upper'], color='lightblue', alpha=0.5, label='信頼区間')

# 予測期間をハイライト
plt.axvline(x=data.index[-1], color='red', linestyle='--', label='予測開始')

# ラベルとタイトル
plt.xlabel('日付')
plt.ylabel('始値')
plt.title('過去のデータを含むSPY時系列予測(対数変換)')
plt.legend()
plt.grid(True)
plt.show()
学習結果および予測結果(全チャート)*赤線以降が予測値

実行結果は上記の通りですが、対数軸や季節性を考慮させたといても、特に直近の2020年のコロナショックやその後の上昇・下落とうまく学習できていません。

3)実践② 説明変数QQQ、TLTを追加

SP500(SPY)のみではうまく学習できていないため、説明変数を追加します。追加する説明変数は、S&P500は特に最近は半導体を中心とするハイテクの動きに影響を受けており、また市場環境として金利の影響が考えられます。そのため、今回はQQQ、TLTの価格を説明変数として、データを読み込み学習させてみました。*その他コードはほぼ同じです。コードを勉強されたい方は実践としてトライしてみてください。

# Yahoo FinanceからSPY、QQQ、およびTLTデータを取得
end_date = date.today().strftime("%Y-%m-%d")  # 終了日は現在の日付
start_date = '2004-01-01'  # 過去のデータの開始日
data = yf.download(['SPY', 'QQQ', 'TLT'], start=start_date, end=end_date)['Open']

今回は、SPYのみの場合より、うまく学習できていることがわかります。ただし、予測期間が短すぎて肝心な予測が見えてません。そこで直近の実績と予測値だけのグラフを出力します。

# 過去3ヶ月と予測期間(30日)をプロット
plt.figure(figsize=(14, 7))

# 3ヶ月前の日付を取得
three_months_ago = data.index[-1] - pd.DateOffset(months=3)

# 過去3ヶ月のデータをフィルタリング
recent_data = data[three_months_ago:]

# 予測期間(次の30日間)をフィルタリング
forecast_period = forecast[forecast['ds'] > data.index[-1]]

# 過去3ヶ月の実際のデータをプロット
plt.plot(recent_data.index, recent_data['SPY'], label='実際のデータ', color='black')

# 次の30日間の予測データをプロット
plt.plot(forecast_period['ds'], forecast_period['yhat'], label='予測', color='blue')
plt.fill_between(forecast_period['ds'], forecast_period['yhat_lower'], forecast_period['yhat_upper'], color='lightblue', alpha=0.5, label='信頼区間')

# ラベルとタイトル
plt.xlabel('日付')
plt.ylabel('始値')
plt.title('過去3ヶ月と次の30日間のSPY時系列予測(対数変換)')
plt.legend()
plt.grid(True)
plt.show()
直近のデータと予測結果のみ出力

実行した結果、直近の価格にくらべ、今後30日間は比較的上目と予測されています。
 *コード全文は下記にあります。

4 まとめ

今回Prophetモデルと使ったS&P500の予測について実践してみました。 
株価予測について信頼できるとは限りませんが、比較的簡単に予測が実行できるため、ご自身のお仕事や興味のある内容について実践してみようと思って頂ければ幸いです。
次回は、ついに話題のAI学習入門で同じS&P500の株価予測のコードを紹介できればと考えています。今後も投資リテラシー向上兼プログラム活用に役立つ情報を発信していきますので応援のほどよろしくお願いします!

*今回の結果は過去の結果を解析したものであり、今後の将来を保証するものではありません。実際の投資にあたってはご自身の判断でお願いいたします。

記事の感想、要望があれば下記X(旧Twitterまで)
*今後の記事に活用させていただきます!!



以下、過去記事、AI時系列予測等のご紹介
他サイトですがココならで、A I(LSTM)を使った株価予測の販売もやってます。こちらではFREDから、失業率や2年10年金利、銅価格等結果も取得しLSTMモデルで予測するコードとなってますので興味があれば見てみてください。またその他2件も米国株投資とは直接関係はありませんがプログラム入門におすすめですのでみてみてください。



チャンネル紹介:Kota@Python&米国株投資チャンネル

過去の掲載記事:興味PYがあればぜひ読んでください。
グラフ化集計の基礎:S &P500と金や米国債を比較してます。

移動平均を使った時系列予測


コード全文:

ここから先は

5,645字

¥ 1,200

期間限定 PayPay支払いすると抽選でお得に!

この記事が気に入ったらサポートをしてみませんか?