日々変動する株価データを題材にPythonにおけるデータ分析のいろはを学んでいく本連載。最終回はローソク足とともにこれまでに計算したオシレーターなど一式を1つのグラフで表示する方法や過去の株価データを基にした株価予測の方法を解説します。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本連載第4回まで、オシレーターの計算とゴールデンクロス/デッドクロスの算出方法を解説しました。連載最終回としてこれまでに表示したグラフを1つにまとめて表示したり、過去の株価データを基に予測したりしてみます。連載の趣旨がデータ分析である以上、Python自体の言語仕様や文法に関しては詳しい説明を割愛する場合があることをご了承ください。
サンプルファイルを実行する場合は、サンプルファイルのリンクを開いた後に、メニューの「ファイル」から「ドライブにコピーを保存」を選択して保存したコピーを「Google Colaboratory」で実行してください。
各オシレーターをグラフで表示するため、これまでに説明して方法で表示する株価データのデータフレームを作成します。pytiとTa-Libをインストールして進めてください。
日本製鉄(5401)の株価を例に、これまでのおさらいを兼ねて表示するデータを準備します。株価の取得とpytiを利用してボリンジャーバンドを計算します。
- from pyti.bollinger_bands import upper_bollinger_band as bb_up
- from pyti.bollinger_bands import middle_bollinger_band as bb_mid
- from pyti.bollinger_bands import lower_bollinger_band as bb_low
- df = get_stock_data(1928)
- data = df['Close'].tolist()
- period = 25
- bb_up, bb_mid, bb_low = bb_up(data, period), bb_mid(data, period), bb_low(data, period)
- df['bb_up'], df['bb_mid'], df['bb_low'] = bb_up, bb_mid, bb_low
Ta-Libを利用して「MACD」(Moving Average Convergence Divergence)と「RSI」(Relative Strength Index)と移動平均を計算します。
- import talib as ta
- close = df['Close']
- macd, macdsignal, _ = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
- df['macd'], df['macd_signal'] = macd, macdsignal
- rsi14, rsi28 = ta.RSI(close, timeperiod=14), ta.RSI(close, timeperiod=28)
- df['rsi14'], df['rsi28'] = rsi14, rsi28
- ma5, ma25, ma75 = ta.SMA(close, timeperiod=5), ta.SMA(close, timeperiod=25), ta.SMA(close, timeperiod=75)
- df['ma5'], df['ma25'], df['ma75'] = ma5, ma25, ma75
移動平均からゴールデンクロスとデッドクロスを算出します。
- import numpy as np
- ma5, ma25 = df['ma5'], df['ma25']
- cross = ma5 > ma25
- cross_shift = cross.shift(1)
- temp_gc = (cross != cross_shift) & (cross == True)
- temp_dc = (cross != cross_shift) & (cross == False)
- gc = [m if g == True else np.nan for g, m in zip(temp_gc, ma5)]
- dc = [m if d == True else np.nan for d, m in zip(temp_dc, ma25)]
- df["gc"], df["dc"] = gc, dc
計算結果を確認するため、グラフを描画させてみます(第4回のときのグラフと同じものです)。直近120日分のデータを表示します。
- import plotly.graph_objs as go
- pdf = df.tail(120)
- layout = {
- 'title' : { 'text': "5401", 'x':0.5 },
- 'xaxis' : { 'title': "日付", 'rangeslider': { 'visible': False } },
- 'yaxis' : { 'title': "価格(円)", 'tickformat': ',' },
- 'plot_bgcolor':'light blue'
- }
- data = [
- go.Candlestick(name="chart", x = pdf.index, open=pdf['Open'], high=pdf['High'], low=pdf['Low'], close=pdf['Close'],
- increasing_line_color= '#00ada9', decreasing_line_color= '#a0a0a0'),
- go.Scatter(x=pdf.index, y=pdf["ma5"], name='MA5', line=dict(color="#ff007f" ,width=1.2)),
- go.Scatter(x=pdf.index, y=pdf["ma25"], name='MA25', line=dict(color='#7fbfff' ,width=1.2)),
- go.Scatter(x=pdf.index, y=pdf["gc"], name="Golden Cross", mode='markers', marker=dict(size = 12, color='blueviolet')),
- go.Scatter(x=pdf.index, y=pdf["dc"], name="Dead Cross", mode='markers', marker=dict(size = 12, color='black', symbol = 'x'))
- ]
- fig = go.Figure(data = data, layout = go.Layout(layout))
- fig.show()
まず、先ほど算出したボリンジャーバンドをグラフに表示します。その際にデータの日付についても調整します。
ボリンジャーバンドは、バンドの上限と下限が株価の変動範囲です。このバンドの幅をグレーでグラフに表示します。サンプル内のグラフに表示するデータを次のように修正します。
- data = [
- # 中略
- go.Scatter(x=pdf.index ,y=pdf["bb_up"], name= '',line=dict(width=0)),
- go.Scatter(x=pdf.index ,y=pdf["bb_low"], name= 'BB',line=dict(width=0), fill='tonexty', fillcolor="rgba(170,170,170,0.25)"),
- ]
バンドの上限と下限を線で描画します。バンド下限のfillプロパティにtonexty(線のY軸まで塗りつぶし)を指定して、線より上の色を指定します。バンドの上限では、色を指定していないので、そこで色を付ける処理が止まります。その結果として、バンドの上限と下限の間に色が付いて株価の変動幅が表示されます。
株価(データフレーム)のindexはDateTime型です。グラフに表示する際には、株価データの存在しない営業日以外の土日祝日もデータがあるものと自動的に解釈されるので、X軸が空いてしまっている部分があります。グラフをマウスで選択すると、選択範囲が拡大できます。
X軸の空きをなくす処理を作成してX軸に空きがないようにします。まずインデックスをDateTime型でない数値の連番に変更します。
- df.reset_index(inplace=True)
reset_indexメソッドでインデックスをリセットします。引数のinplaceにTrueを指定して連番のインデックスを振り直します。次に、グラフに表示する際にインデックスに対応した日付を表示する処理を作成します。
振り直した連番のインデックスに対応する日付を表示すれば、X軸に日付は表示されます。ただし、そのまま日付を表示すると、全ては表示できなかったり、重なって表示されたりするため、3日に1日のみ表示するようにします。データフレームのDateカラムを利用して3日に1日の日付を取り出す処理は次のように考えられます。
3日に1日の日付を取り出した後に、その日付をX軸に表示する処理は次のように書くことができます。
- # 3日に1日の日付を取り出す
- days_list = [df.index[idx:idx + 3] for idx in range(0,len(df.index), 3)]
- dates = [df['Date'][r[0]] for r in days_list]
- # X軸を更新
- fig['layout'].update({
- 'xaxis':{
- 'showgrid': True,
- 'tickvals': np.arange(0, df.index[-1],3),
- 'ticktext': [x.strftime('%m/%d') for x in dates],
- }
- })
plotly.graph_objsのupdateメソッドを利用して、x軸(xasis)に対する表示を変更します。updateメソッドで指定できるプロパティには次のものがあります。
名前 | 概要 |
---|---|
showgrid | グリッドに表示するか |
tickvals | 表示するインデックスのリスト |
ticktext | 表示する文字列のリスト |
レイアウトで指定するプロパティ |
tickvalsプロパティで指定したインデックスに対応する日付を、ticktextプロパティで指定します。サンプルでは、MM/DDの書式で日付を表示しています。
サンプルを実行すると、データのない営業日以外の土日祝日を除いたグラフを表示します。ローソク足が途切れずに表示されていることを確認してみてください。
Copyright © ITmedia, Inc. All Rights Reserved.
Coding Edge 髫ェ蛟�スコ荵斟帷ケ晢スウ郢ァ�ュ郢晢スウ郢ァ�ー