こんにちは。TATです。
今日のテーマは「PythonのPlotlyで株価のローソク足チャートを描く方法」です。
Pythonで株価のローソク足チャートを描くためのライブラリはいくつかありますが、ここではPlotlyに焦点を当てます。
Plotlyを使えば、ホバーするとデータが表示されたり、チャートを拡大・縮小したりとインタラクティブなチャートを簡単に描くことができます。
ローソク足チャートにも対応しており、株やFXの分析にも有用です。
本記事では、Plotlyで株価のローソク足チャートを描き、さらに複数のテクニカル指標もあわせて表示する方法について解説します。
また、ラベル名の変更や営業日のみを表示する方法など、チャートをカスタマイズする方法についても紹介します。
(おさらい)株価のローソク足データを取得する
まずはおさらいとして、計算に必要な株価のローソク足データを取得します。
こちらについては過去の記事でも解説しているので詳細は割愛します。
次のコードでは、pandas_datareaderを使ってトヨタ(証券コード: 7203)のローソク足データを取得します。
期間は2021年の1年間としました。
from pandas_datareader import data df = data.DataReader("7203.T", "yahoo", start="2021-01-01", end="2021-12-31") df.head()
これでデータの準備は完了です。
【日本株対応】Pythonで株価のローソク足データを取得する方法まとめ【CSV、ライブラリ、スクレイピング】
続きを見る
Plotlyでローソク足チャートを描く
ここから、Plotlyを使ってローソク足チャートを描いていきます。
plotly.graph_objects.Candlestick
Plotlyでローソク足チャートを描くためには、Plotly.graph_objects.Candlestickを使います。
ここにx(日時データ), open(始値), high(高値), low(安値), close(終値)を指定すればOKです。
import plotly.graph_objects as go fig = go.Figure( data=[go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False))] ) fig.show()
ローソク足チャートを描くことができました。
とても簡単ですね。
インタラクティブにチャートを動かせる
Plotlyで表示されるデータはHTML形式になっており、インタラクティブに扱うことができます。
こちらにHTML形式のものを貼りました。(もしかしたらスマホとかで画面がはみ出しりするかも。。。)
カーソルを合わせるとデータが表示されたり、チャートの拡大や縮小ができます。
特定の期間を拡大して確認できたりするのでとても便利です。
HTML形式で表示するのはここだけにして、残りは全て画像で貼っていきます(HTML形式にするとファイル容量が重いんですw)
下にあるバーは消した方がスッキリする
ローソク足チャートの下には、期間を指定できるバーがありますが、こちらは消すことも可能です。
チャートを直接いじくれるので、僕は基本的にここはなしに設定しています。
この場合はfig.update(layout_xaxis_rangeslider_visible=False)と追加すればOKです。
import plotly.graph_objects as go fig = go.Figure( data=[go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False))] ) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
これでバーは消えて、ローソク足チャートだけが表示されるようになりました。
以降、このバーは全て非表示にします。
タイトル・ラベルの追加、フォーマットの変更
次にタイトルなどの情報を追加します。
あとはy軸のラベル名をつけたり、日付や株価のフォーマットも変更してみます。
import plotly.graph_objects as go fig = go.Figure( data=[go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False))] ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, yaxis_title='株価', xaxis_title="Date", ) # 日付のフォーマット変更 fig.update_xaxes(tickformat='%Y/%m/%d') # 株価のフォーマット変更(カンマ区切り) fig.update_yaxes(separatethousands=True) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
ちょっとコードは長くなってしまいますが、細かいフォーマットの指定が可能です。
タイトルなどを設定するにはupdate_layoutを使います。
ここでタイトルやx軸やy軸の名前も指定できます。
タイトルでは、xとyを指定していますが、これは0〜1の範囲で指定します。
x=0.5というのは横軸でちょうど真ん中という意味です。y=0.9はチャートの縦軸でほぼ一番上を指します。(y=1だと文字がはみ出ます)
xaxis_titleやyaxis_titleは名前の通りですね。
そして各軸のフォーマットを変更するには、update_xaxesやupdate_yaxesを使います。
これで日付のフォーマットを指定したり、数値をカンマ区切りにして表示したりすることができます。
これで諸々必要な情報を書き込むことができました。
営業日のみを表示する
最後に営業日のみだけを表示するようにチャートをいじくってみます。
ここが結構ポイントで、これまでのチャートをよく見ると、所々不自然な空白期間があります。
先ほどのHTMLのチャートを拡大してみてください。
この空白は、土日と祝日によるものです。
デフォルトでは、すべての日付が表示されるため、データの存在しない日も表示されてしまいます。
より見やすいチャートにするためには、株式市場が開いている営業日のみを表示する必要があります。
Plotlyには、特定のデータを非表示にするrangebreaksという設定があります。
これを利用すれば、不要な日付(土日祝)を隠すことができます。
非表示にしたい日付データをリスト形式で指定すればOKです。
不要な日付リストを抽出
先ほど取得したトヨタの株価データの日付をもとに、非表示にしたい日付をリストアップします。
pandasのdate_rangeを使って日付の一覧を取得し、株価データの日付に入っていないものを炙り出します。
import pandas as pd #日付一覧を取得 d_all = pd.date_range(start=df.index[0],end=df.index[-1]) #株価データの日付リストを取得 d_obs = [d.strftime("%Y-%m-%d") for d in df.index] # 株価データの日付データに含まれていない日付を抽出 d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs]
d_breaksが非表示にしたい日付リストになります。
チャートに反映する
このd_breaksを非表示するように指定してあげると、営業日のみのローソク足チャートが描けるようになります。
import plotly.graph_objects as go fig = go.Figure( data=[go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False))] ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, yaxis_title='株価', xaxis_title="Date", ) fig.update_xaxes( rangebreaks=[dict(values=d_breaks)], # 非営業日を非表示設定 tickformat='%Y/%m/%d' # 日付のフォーマット変更 ) # 株価のフォーマット変更(カンマ区切り) fig.update_yaxes(separatethousands=True) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
update_xaxesでrangebreaksを指定しました。
これで営業日のみを表示することができ、不自然な空白はなくなりました。
以上が、基本的なローソク足の描き方になります。
複数のチャートを組み合わせる
ここからは少し応用編です。
ここまでの内容で、Plotlyで株価のローソク足チャートを描くことができました。
次に、複数のグラフを組み合わせて表示する方法について解説していきます。
出来高や移動平均線など、いろいろなテクニカル指標を追加してみます。
plotly.subplots.make_subplotsで複数のチャートを描く
Plotlyで複数のチャートを描くためには、plotly.subplots.make_subplotsを使います。
これを使うと、複数のチャートを描いたり、同じチャートの中に複数のグラフを描くことができるようになります。
matplotlibのsubplotsとほぼ同じような使い方です。
基本的な使い方としては、subplotsでfigを定義し、fig.add_traceで各チャートにグラフを追加していく流れになります。
出来高を追加する
まずは手始めに出来高を追加してみます。
まずはコードを公開
まずはコードをどうぞ。なるべく多くコメントをつけました。
import plotly.graph_objects as go from plotly.subplots import make_subplots # figを定義 fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date") # Candlestick fig.add_trace( go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False), row=1, col=1 ) # Volume fig.add_trace( go.Bar(x=df.index, y=df["Volume"], showlegend=False), row=2, col=1 ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, ) fig.update_xaxes( rangebreaks=[dict(values=d_breaks)], # 非営業日を非表示設定 tickformat='%Y/%m/%d' # 日付のフォーマット変更 ) # ラベル名の設定とフォーマット変更(カンマ区切り) fig.update_yaxes(separatethousands=True, title_text="株価", row=1, col=1) fig.update_yaxes(title_text="出来高", row=2, col=1) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
ローソク足チャートに出来高を加えることができました。
コード解説
make_subplotsで、rows(行)とcols(列)を指定し、shared_xaxes=Trueとしてx軸を共有するように設定します。
x_titleでxのラベル名を設定しています。
vertical_spacingはチャート間の隙間の大きさで0〜1で指定します。
この設定は好みですが、僕はだいたい0.05にすることが多いです。適宜調整してみてください。
row_widthではrow(行)の高さを指定します。x_titleはその名の通り、x軸名です。
y軸名は2つあるので、fig.update_yaxesを使ってそれぞれ指定します。
add_traceでrowとcolを指定することで、任意の場所にチャートを描くことができます。
1行目にローソク足チャート、2行目に出来高の棒グラフを描けばOKです。
移動平均線を追加する
次に移動平均線を追加します。
ここでは20日、50日、200日移動平均線を加えてみます。
rolling()で移動平均線を計算
まずは移動平均線を計算します。
計算方法についてこちらの記事で解説しているので詳細は割愛します。
# SMAを計算 df["SMA20"] = df["Close"].rolling(window=20).mean() df["SMA50"] = df["Close"].rolling(window=50).mean() df["SMA200"] = df["Close"].rolling(window=200).mean() df.tail()
これで移動平均線の計算はOKです。
【コード解説】Pythonで株価データから主要なテクニカル分析を計算して可視化する【移動平均線、MACD、RSI】
続きを見る
ローソク足チャートに移動平均線を加える
それでは、ローソク足チャートに先ほど計算した移動平均線を加えてみます。
import plotly.graph_objects as go from plotly.subplots import make_subplots # figを定義 fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date") # Candlestick fig.add_trace( go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False), row=1, col=1 ) # 移動平均線 fig.add_trace(go.Scatter(x=df.index, y=df["SMA20"], name="SMA20", mode="lines"), row=1, col=1) fig.add_trace(go.Scatter(x=df.index, y=df["SMA50"], name="SMA50", mode="lines"), row=1, col=1) fig.add_trace(go.Scatter(x=df.index, y=df["SMA200"], name="SMA200", mode="lines"), row=1, col=1) # Volume fig.add_trace( go.Bar(x=df.index, y=df["Volume"], showlegend=False), row=2, col=1 ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, ) fig.update_xaxes( rangebreaks=[dict(values=d_breaks)], # 非営業日を非表示設定 tickformat='%Y/%m/%d' # 日付のフォーマット変更 ) # ラベル名の設定とフォーマット変更(カンマ区切り) fig.update_yaxes(separatethousands=True, title_text="株価", row=1, col=1) fig.update_yaxes(title_text="出来高", row=2, col=1) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
移動平均線が加えられました。
ここまで来ればチャート分析にも活用できるレベルになってきます。
複数のテクニカル指標を組み合わせる
最後に複数のテクニカル指標を組み合わせて表示してみます。
ここまで使用してきた出来高と移動平均線に加えて、MACDとRSIも追加してみます。
Pythonによるこれらのテクニカル指標の計算方法についてはこちらの記事で紹介しています。
MACDとRSIを計算する
まずはMACDとRSIを計算します。
ここではそれぞれを計算するための関数を定義してみました。
def macd(df): FastEMA_period = 12 # 短期EMAの期間 SlowEMA_period = 26 # 長期EMAの期間 SignalSMA_period = 9 # SMAを取る期間 df["MACD"] = df["Close"].ewm(span=FastEMA_period).mean() - df["Close"].ewm(span=SlowEMA_period).mean() df["Signal"] = df["MACD"].rolling(SignalSMA_period).mean() return df def rsi(df): # 前日との差分を計算 df_diff = df["Close"].diff(1) # 計算用のDataFrameを定義 df_up, df_down = df_diff.copy(), df_diff.copy() # df_upはマイナス値を0に変換 # df_downはプラス値を0に変換して正負反転 df_up[df_up < 0] = 0 df_down[df_down > 0] = 0 df_down = df_down * -1 # 期間14でそれぞれの平均を算出 df_up_sma14 = df_up.rolling(window=14, center=False).mean() df_down_sma14 = df_down.rolling(window=14, center=False).mean() # RSIを算出 df["RSI"] = 100.0 * (df_up_sma14 / (df_up_sma14 + df_down_sma14)) return df # MACDを計算する df = macd(df) # RSIを算出 df = rsi(df) df.head()
これでMACDとRSIの計算ができました。
Plotlyですべてのテクニカル指標をまとめて描画する
最後にPlotlyでこれらをすべてまとめて描いてみましょう。
今回はローソク足、出来高、MACD、RSIの4チャートを描くので、rowsは4になります。
あとはこれまでと同様にadd_traceでチャートを追加しておけばOKです。
ちょっとコードとしては長くなります。
import plotly.graph_objects as go from plotly.subplots import make_subplots # figを定義 fig = make_subplots(rows=4, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.2, 0.2, 0.7], x_title="Date") # Candlestick fig.add_trace( go.Candlestick(x=df.index, open=df["Open"], high=df["High"], low=df["Low"], close=df["Close"], showlegend=False), row=1, col=1 ) # 移動平均線 fig.add_trace(go.Scatter(x=df.index, y=df["SMA20"], name="SMA20", mode="lines"), row=1, col=1) fig.add_trace(go.Scatter(x=df.index, y=df["SMA50"], name="SMA50", mode="lines"), row=1, col=1) fig.add_trace(go.Scatter(x=df.index, y=df["SMA200"], name="SMA200", mode="lines"), row=1, col=1) # MACD fig.add_trace(go.Scatter(x=df.index, y=df["MACD"], mode="lines", showlegend=False), row=3, col=1) fig.add_trace(go.Scatter(x=df.index, y=df["Signal"], mode="lines", showlegend=False), row=3, col=1) # RSI fig.add_trace(go.Scatter(x=df.index, y=df["RSI"], mode="lines", showlegend=False), row=4, col=1) # Volume fig.add_trace( go.Bar(x=df.index, y=df["Volume"], showlegend=False), row=2, col=1 ) # Layout fig.update_layout( title={ "text": "トヨタ自動車(7203)の日足チャート", "y":0.9, "x":0.5, }, height=700 ) fig.update_xaxes( rangebreaks=[dict(values=d_breaks)], # 非営業日を非表示設定 tickformat='%Y/%m/%d' # 日付のフォーマット変更 ) # ラベル名の設定とフォーマット変更(カンマ区切り) fig.update_yaxes(separatethousands=True, title_text="株価", row=1, col=1) fig.update_yaxes(title_text="出来高", row=2, col=1) fig.update_yaxes(title_text="MACD", row=3, col=1) fig.update_yaxes(title_text="RSI", row=4, col=1) fig.update(layout_xaxis_rangeslider_visible=False) #追加 fig.show()
キレイに表示できました。
MACDやRSIの追加については、出来高を追加した時と同じ要領です。
rowだけを変更すれば任意の場所にグラフを加えることができます。
rowが増えたので、update_yaxesもこれに合わせて追加しました。
また、デフォルトの設定だとチャートが縦に潰れていたので、update_layoutの中でwidthを指定することで、すこしグラフを縦に伸ばしました。
ここまでいろいろな情報をまとめて表示することができると、本格的なテクニカル分析にも利用することができますね。
Plotlyであれば、拡大・縮小して特定期間のデータを詳しくみたり、ホバーして詳細な情報を確認できたりするので、とても使い勝手がいいです。
データの分析・可視化にはPythonが最適!
本記事で紹介したコードは、全てPythonを使って書いています。
Pythonはデータの分析や可視化を得意とするプログラミング言語で、さらにAI関連のライブラリーも豊富で昨今のAIブームで需要が急拡大しています。
→ 【いますぐ始められます】データ分析をするならPythonが最適です。
また、Pythonは比較的学びやすい言語でもあります。
実際、僕は社会人になってからPythonを独学で習得して転職にも成功し、Python独学をきっかけに人生が大きく変わりました。
→ 【実体験】ゼロからのPython独学を決意してから転職を掴み取るまでのお話。
Pythonの学習方法についてはいろいろな方法があります。
僕はUdemyを選びましたが、書籍やプログラミングスクールも選択肢になります。
→ 【決定版】Python独学ロードマップ【完全初心者からでもOKです】
→ 【まとめ】Pythonが学べるおすすめプログラミングスクール
→ プログラミングの独学にUdemyをおすすめする理由!【僕はUdemyでPythonを独学しました!】
まとめ
本記事では、「PythonのPlotlyで株価のローソク足チャートを描く方法」というテーマで解説しました。
Plotlyを使えば、インタラクティブなチャートを簡単に描くことができます。
ローソク足チャートにも対応しており、株やFXの分析にも活用することができます。
本記事で紹介したコードを利用すれば、ローソク足チャートに加えてさまざまなテクニカル指標も合わせて描画することができます。
営業日のみの表示やラベルのフォーマットの変更など、細かいカスタマイズも可能です。
是非とも、ご活用ください。
また、Plotly以外のローソク足チャートを描けるライブラリとしては、mplfinanceがあります。
こちらはインタラクティブなチャートではありませんが、Plotlyより短いコードで簡単にキレイなローソク足チャートを描くことができるのでおすすめです。
Pythonのmplfinanceで株価のローソク足チャートを描く方法【コード解説】
続きを見る
ここまで読んでくださり、ありがとうございました。