読者です 読者をやめる 読者になる 読者になる

今日も窓辺でプログラム

外資系企業勤めのエンジニアが勉強した内容をまとめておくブログ

Pythonでローソク足と出来高を1つのチャートに簡単に描く方法

今回やること

Pythonを使ってYahoo!ファイナンスの株価時系列データを読み込み、ロウソク足と出来高のチャートをひとつの図に描く方法を紹介します。
データの読み込みにpandas、描画にはmatplotlibを使用します。

使用するデータと環境

今回はPython3.5, matplotlibは1.5.3を使用します。
特に、今回使用するfinance apiは、バージョン1.4からdeprecatedとなっており、将来的にmpl_toolkits等のほかの場所に移動される予定ですので、matplotlibのバージョンにはお気を付けください。

また、使用するデータはYahoo!ファイナンスから2016年上半期の日経平均のデータを落としてきて使用します。こちらのページのDownload Dataというリンクからダウンロードできます。

今回使用したJupyter NotebookはGitHubにアップロードしてあります。
github.com

下準備

まずはダウンロードしたCSVをpandas.read_csvを使って読み込みます。
読み込み部分のコードについては、以前の記事でも少し解説しています。

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ohlc, volume_overlay
%matplotlib inline

# 2016年上半期の日経平均のデータを読み込む
start_date = "2016-01-01"
end_date = "2016-06-30"
df = pd.DataFrame(index=pd.date_range(start_date, end_date))
df = df.join(pd.read_csv("n225.csv", index_col="Date", parse_dates=True))
df = df.dropna()

これで、こんな形のデータフレームが用意できました。
f:id:kanohk:20170109150439p:plain

ローソク足の描画

ローソク足の描画には、matplotlib.financecandlestick2_ohlcという関数を使用します。
この関数にはいくつか亜種が存在しますが本質的に渡すべきデータはどれも同じで、始値、終値、高値、安値をそれぞれ渡します。
matplotlib自体の細かい使い方は省略しますが、candlestick2_ohlcでローソク足を描いたあと、x軸とy軸のラベルや範囲等を正しく設定したら完成です。
今回は丁寧にラベルも書きましたが、手元で分析するだけならこの部分のコードはなくてもよいかもしれません。

# ローソクだけをプロット
fig = plt.figure(figsize=(18, 9))
ax = plt.subplot(1, 1, 1)

# candlestick2を使って描画
candlestick2_ohlc(ax, df["Open"], df["High"], df["Low"], df["Adj Close"], width=0.9, colorup="b", colordown="r")

# 軸メモリやラベルを整える
ax.set_xticklabels([(df.index[int(x)].strftime("%Y/%M/%D") if x <= df.shape[0] else x) for x in ax.get_xticks()], rotation=90)
ax.set_xlim([0, df.shape[0]]) # 横軸の範囲はデータの個数(df.shape[0]個)までに変更しておく
ax.set_ylabel("Price")

f:id:kanohk:20170109150506p:plain

出来高の描画

ローソク足チャートはすでにかけているので、そこに出来高を追加していきます。
出来高は、volume_overlayという関数を使って描画します。今回は緑色で描画していますが、陰線か陽線かで色を分けることもできます。

# ローソク足をプロット
fig = plt.figure(figsize=(18, 9))
ax = plt.subplot(1, 1, 1)
candlestick2_ohlc(ax, df["Open"], df["High"], df["Low"], df["Adj Close"], width=0.9, colorup="b", colordown="r")
ax.set_xticklabels([(df.index[int(x)].strftime("%Y/%M/%D") if x <= df.shape[0] else x) for x in ax.get_xticks()], rotation=90)
ax.set_xlim([0, df.shape[0]]) # 横軸の範囲はデータの個数(df.shape[0]個)までに変更しておく
ax.set_ylabel("Price")

# ローソク足を上側75%に収める
bottom, top = ax.get_ylim()
ax.set_ylim(bottom - (top - bottom) / 4, top)


# 出来高のチャートをプロット
ax2 = ax.twinx()
volume_overlay(ax2, df["Open"], df["Adj Close"], df["Volume"], width=1, colorup="g", colordown="g")
ax2.set_xlim([0, df.shape[0]])

# 出来高チャートは下側25%に収める
ax2.set_ylim([0, df["Volume"].max() * 4])
ax2.set_ylabel("Volume")

ローソク足と出来高を描画したあと、それぞれ上方向と下方向にチャートを縮めています。
こうしないと、出来高とローソク足が重なって描画され、何が何だかわからなくなるからです。
この移動は、set_ylimというy軸の範囲を設定する関数を使用して行っています。
完成したチャートはこんな感じです。

f:id:kanohk:20170109151032p:plain


関連記事

テクニカル指標を日経平均に対して計算して可視化してみました。
www.madopro.net

Jupyter Notebookの簡単な解説記事はこちら。
www.madopro.net

金融データをpandasで時系列順に読み込む方法はこちら。
www.madopro.net