x0907-成果物:SARIMAモデルを使ったソフトバンクの株価予測



はじめに

 今回、ソフトバンクの株価分析を成果物のテーマ選定にした理由はAidemyで学習した内容を用いてアウトプットをすることにより学習をより深めたかったということと現在金融業界に努めているので今回の成果物を皮切りにこれから今まで学習した内容を応用して実際にも役に立つレベルのものを創作したいと考えたからです。
 実際にいろいろやってみたいことが見つかったので、自分のスキルを向上させて実現させていきたいと思いました。

1.目的


 i.SARIMAモデルが株価予測に有効であるかを検証すること
 ii.結果と原因の関係を追及すること
 iii.他に有効な手段があるか探すこと

2.用いた手法、予測に使用した銘柄の紹介


1)手法の紹介

・GoogleColaboratoryにてPython3を使用
・時系列予測を用いて、終値ベースで一定期間の株価を予測し、同じ期間の 
 実測値と比較をした。コードはAidemyの講座を参照した。

2)銘柄の紹介

・ソフトバンクグループ【9984】

3.コードの解説

1)株価データを取得するためのプログラム作成

「株価の時系列予測」を行うために、「yahoofinance」から株価データを引用するためのコードを入力。これを土台として、今後のコードを組み立てていく。

#1)株価データを取得するためのプログラム作成

!pip install mplfinance japanize-matplotlib

2)ローソク足チャートの設定

時系列予測をグラフとして可視化した上で予測値と実測値の乖離について調べたいので、ここではグラフを出力・設定をするためのコードを作成した。
まずはyahoofinanceを引用するためのコードを作成し、次にグラフを表示した際の設定についてコードを作成した。

#2)ローソク足チャートの出力・設定
# yfinanceの導入(株データ取得のプログラム)
import yfinance as yf
from datetime import datetime
df = yf.download("9984.T").dropna()

import mplfinance as mpf
import japanize_matplotlib

import pandas as pd
import itertools

# グラフの設定(銘柄名の表示,ローソク足チャートを設定)
symbols=9984
name="softbank"

mpf.plot(df, title=name+"_日足チャート", type="candle", mav=(25, 50, 75), datetime_format="%Y/%m/%d", tight_layout=False, volume=True, figratio=(19,9),  savefig=str(symbols)+"_daily.png")

3)移動平均線の計算、チャートグラフの出力

 これまでの株価の推移を把握するためにチャートを表示する。

#3)移動平均線の計算、チャートグラフの出力
# 対象期間は、2023/1/4∼2024/2/28
# 移動平均線の計算
df["SMA25"] = df["Close"].rolling(window=25).mean()
df["SMA50"] = df["Close"].rolling(window=50).mean()
df["SMA75"] = df["Close"].rolling(window=75).mean()

# チャートグラフの出力
import matplotlib
%matplotlib inline

# チャートグラフの表示設定
df_start = df.loc[datetime(2022,1,4).strftime("%Y-%m-%d"):]

mpf.plot(df_start, title=name+"_chart", type="candle", mav=(25, 50, 75), datetime_format="%Y/%m/%d", tight_layout=False, volume=True, figratio=(19,9), style="yahoo")

add_day_ave = [
                  mpf.make_addplot(df_start["SMA25"], panel=0, color="b", width=1, alpha=0.7),
                  mpf.make_addplot(df_start["SMA50"], panel=0, color="g", width=1, alpha=0.7),
                  mpf.make_addplot(df_start["SMA75"], panel=0, color="r", width=1, alpha=0.7)
               ]
mpf.plot(df_start, type='candle',datetime_format='%m/%d',xrotation=360, tight_layout=False, volume=True, figratio=(19,9),  style='yahoo')

df.loc[datetime(2022,1,4).strftime("%Y-%m-%d"):]


4)時系列予測

この節では、実際に時系列予測を行った。

4-1: 時系列予測を設定
予測のためのコードを入力、実際に予測をする範囲を設定した。
(予測範囲は、2024/2/1~2/28で設定)

#4-1:時系列予測を設定
# 時系列予測のコード
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm
from pandas import datetime

# 予測範囲を設定(日付はISO formatで指定)
pred_index = pd.date_range("2024-02-01", "2024-02-28")

4-2: 予測範囲を出力
前段階を踏まえて、予測範囲の出力した。
時系列で予測する営業日は10日で設定(休日/祝日は市場が動かないため)。

4-2:予測範囲を出力(予測する営業日は10日で設定)
df.tail(10)

4-3: 終値でdfを作成
終値を基準として、dataframeを作成。
基準を終値とした理由は、移動平均線が終値をベースとした指標であるため、移動平均線に沿った形で比較・検討がしやすい終値を基準とした。

#4-3:終値でdfを作成
df['Close'].index

4-4: 1/31までの終値を整理
2024/2/1~2/14を予測するための準備として、2024/1/31までのデータを整理するコードを作成した。休日/祝日については、市場が動かないことを考慮して市場が動いた最終日と同じ価格が表示されるように設定した。

#4-4:1/31までの終値を整理
# 終値で1/31まで出力
stock_price_close = df['Close'].loc[:"2024-01-31"].copy().asfreq('D')
stock_price_close.tail(15)

# 休日,祝日などの取引が行われなかった日は前日の終値を表示(価格が動いていないと考える)
stock_price_close = stock_price_close.ffill()
stock_price_close.tail(15)


4-5: SARIMAモデル導入の前段階
ここは、Aidemyの時系列予測の添削課題のコードを流用した。
周期パラメータについては、添削課題と異なったため7日(1週間)で設定。
30日(1か月)で設定しようとしたが、コードを読み込み切れなかった。

#4-5:SARIMAモデル導入の前段階
def selectparameter(DATA, s):
    p = d = q = range(0, 2)
    pdq = list(itertools.product(p, d, q))
    seasonal_pdq = [(x[0], x[1], x[2], s) for x in list(itertools.product(p, d, q))]
    parameters = []
    BICs = np.array([])
    for param in pdq:
        for param_seasonal in seasonal_pdq:
            try:
                mod = sm.tsa.statespace.SARIMAX(DATA,
                                                order=param,
                                                seasonal_order=param_seasonal)
                results = mod.fit()
                parameters.append([param, param_seasonal, results.bic])
                BICs = np.append(BICs, results.bic)
            except:
                continue
    return parameters[np.argmin(BICs)]

# 周期パラメータは取引所の営業日を考慮して7日に設定
best_params = selectparameter(stock_price_close, 7)

4-6: SARIMAモデルを導入,予測を実行, 実測値と予測値をグラフに反映
SARIMAモデルを使って予測を実行した。その上で、実測値(青線)と予測値(赤線)をグラフに反映し乖離について分析を行った。


4-7 実際の値と予測値の比較の表を作る前処理


#4-7 実際の値と予測値の比較の表を作る前処理
stock_price_actual = df['Close'].loc["2024-02-01":"2024-02-28"].copy().asfreq('D')
stock_price_actual = stock_price_actual.ffill()
pred_df = pd.DataFrame()
pred_df['pred'] = pred
pred_df['actual'] = stock_price_actual["2024-02-01":"2024-02-28"]

4-8 実際の値と予測値の比較

print(pred_df)


5.予測結果に対する考察

予測結果と実測値が相反する動きになったことに対して、以下の要因が関係されるのではないかと考察する。

1)期間の設定が不十分であったため、適切な分析ができなかった。
今回は7日を指定したが、株価の予測において1週間は周期性を考えるのには不十分であるため、可能であるならば1か月、1クール、1年間とSARIMAで分析をしたかった。

2)前処理が適切にされていなかったから。
box-cox変換などを用いて、しっかりデータを調節して行えば適切な結果が出たの出た可能性がある。

3)SARIMAモデルが株価予測に向いていなかった可能性がある。
株価は一応周期性は見られるものの普遍的ではなく、業績やニュースなどの影響が高く、ほかの要素を組み入れる必要があった。

6.今後の課題

1.今回の反省を生かして株価予測に適した方法で分析をする。
データのチューニングや分析方法をいろいろ試す。

2.SARIMAモデルをほかの周期的な予測に適した分析テーマに用いる。今回は講座で習ったSARIMAモデルを興味のあった株価予測に用いたが、周期性の高いテーマに用いることによって意義のある分析結果を出せる可能性を高められると考える。

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