pandas, Matplotlib(mplfinance)でローソク足チャートを作成

Modified: | Tags: Python, pandas, Matplotlib, 時系列データ

pandasとMatplotlib(mplfinance, mpl_finance)を使ってローソク足チャート(Candlestick chart)を描画・作成する方法について、以下の内容を説明する。

  • matplotlib.financeとmpl_finance, mplfinance
  • mplfinanceでローソク足チャート(Candlestick chart)を作成
    • データ準備
    • グラフ作成・画像ファイル保存: 引数savefig
    • 比率: 引数figratio
    • プロットタイプ: 引数type
    • 出来高(Volume): 引数volume
    • 移動平均線: 引数mav
    • 全体のスタイル: 引数style
    • ダウンサンプリング(日足から週足に変換)
  • [参考] mpl_financeでローソク足チャート(Candlestick chart)を作成

ローソク足チャートの元となるOHLCデータの算出やダウンサンプリングについての詳細は以下の記事を参照。

matplotlib.financeとmpl_finance, mplfinance

ローソク足チャートを含む金融関係のグラフ描画機能はもともとmatplotlib.financeとしてMatplotlibに含まれていたが、Matplotlibバージョン2.0からmpl_financeという別のパッケージとして切り出された。ドキュメントはMatplotlibの公式サイトに残されている。

さらにmplfinanceという新たなパッケージが作られ、2020年5月23日現在はmpl_financeはDEPRECATEDでmplfinanceの使用が推奨されている。

mplfinanceはMatplotlibとは別にインストールする必要がある。pip(環境によってはpip3)などを使う。

$ pip install mplfinance

mplfinanceでローソク足チャート(Candlestick chart)を作成

ここからはmplfinanceを使ってローソク足チャート(Candlestick chart)を作成する方法について説明する。

サンプルコードで使用したmplfinanceのバージョンは0.12.4a0。mplfinanceは活発に開発が進められているため、機能が変更・更新されている場合があるので注意。

公式の説明が充実しているのでそちらも参照されたい。

データ準備

ここではpandas-datareaderで取得して保存したApple(AAPL)の株価データを例とする。

pd.read_csv()parse_dates=Trueとして時系列データのpandas.DataFrameとして読み込み、さらに['2017']で2017年のデータを抽出する。

parse_dates=Trueを省略すると行名indexが文字列として読み込まれmplfinanceのplot()では処理できなくなるので要注意。

import pandas as pd
import mplfinance as mpf

df = pd.read_csv('data/src/aapl_2015_2019.csv', index_col=0, parse_dates=True)['2017']
print(df)
#               open      high      low   close    volume
# 2017-01-03  115.80  116.3300  114.760  116.15  28781865
# 2017-01-04  115.85  116.5100  115.750  116.02  21118116
# 2017-01-05  115.92  116.8642  115.810  116.61  22193587
# 2017-01-06  116.78  118.1600  116.470  117.91  31751900
# 2017-01-09  117.95  119.4300  117.940  118.99  33561948
# ...            ...       ...      ...     ...       ...
# 2017-12-22  174.68  175.4240  174.500  175.01  16052615
# 2017-12-26  170.80  171.4700  169.679  170.57  32968167
# 2017-12-27  170.10  170.7800  169.710  170.60  21672062
# 2017-12-28  171.00  171.8500  170.480  171.08  15997739
# 2017-12-29  170.52  170.5900  169.220  169.23  25643711
# 
# [251 rows x 5 columns]

mplfinanceのplot()の仕様に合わせて列名columnsを変更する。Open, Closeのように、大文字小文字も合っていないとダメ。

df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']

pandas.DataFrameはどのように作成してもいいが、indexDatetimeIndexである時系列データで、列名がOpen, Close...となっている必要がある。

グラフ作成・画像ファイル保存: 引数savefig

plot()の引数にpandas.DataFrameを指定する。

mpf.plot(df, savefig='data/dst/candlestick_mpf.png')

mplfinance plot

ここでは引数savefigにパスを指定して画像ファイルとして保存しているが、Jupyter Notebookではmpf.plot(df)とすると出力セルにグラフが表示される。

Jupyter Notebookの場合、引数savefigを指定してもグラフが表示される。入力セルの先頭にマジックコマンド%%captureをつけると表示されなくなる。

%%capture
mpf.plot(df, savefig='data/dst/candlestick_mpf.png')

便宜上、サンプルコードのpyファイルにも%%captureが記載されているが、pyファイルを実行する場合は削除する必要があるので注意。

mplfinanceの画像ファイル保存についての詳細は以下を参照。

比率: 引数figratio

引数figratioでグラフの縦横の比率(アスペクト比)を指定できる。

mpf.plot(df[50:100], figratio=(12,4),
         savefig='data/dst/candlestick_mpf_figratio.png')

mplfinance plot figratio

データ数が多いと見にくいので[50:100]で範囲を絞っている。適当に決めた値で特に意味はない。

プロットタイプ: 引数type

グラフのタイプを引数typeで指定できる。デフォルトは日本ではあまり見ないタイプだが、type='candle'とするとおなじみのローソク足になる。

mpf.plot(df[50:100], type='candle', figratio=(12,4),
         savefig='data/dst/candlestick_mpf_candle.png')

mplfinance plot candle

そのほか'line''pnf'などもある。

色などの変更は後述の引数styleを使う。

出来高(Volume): 引数volume

引数volumeTrueとすると、出来高(Volume)も描画される。

mpf.plot(df[50:100], type='candle', volume=True, figratio=(12,4),
         savefig='data/dst/candlestick_mpf_volume.png')

mplfinance plot volume

当然ながら、元のpandas.DataFrameVolume列が必要。

移動平均線: 引数mav

引数mavで移動平均線(Moving Average)を追加できる。整数intで単独の移動平均線を、整数intを要素とするタプルやリストで複数の移動平均線を追加できる。

mpf.plot(df[50:100], type='candle', volume=True, mav=(5, 25), figratio=(12,4),
         savefig='data/dst/candlestick_mpf_mav.png')

mplfinance plot moving average

例えば5と指定すると5点のデータの平均(日次データであれば5日移動平均線)となる。

全体のスタイル: 引数style

引数styleで全体のスタイルを変更できる。

mpf.plot(df[50:100], type='candle', figratio=(12,4),
         volume=True, mav=(5, 25), style='yahoo',
         savefig='data/dst/candlestick_mpf_style_yahoo.png')

mplfinance plot style yahoo

様々なスタイルが選択可能。自分で作成することもできる。

ダウンサンプリング(日足から週足に変換)

日足から週足や月足、年足のチャートを作成したい場合は元のデータをダウンサンプリングする。

OHLCVデータのダウンサンプリングにはresample()メソッドを使う。

d_ohlcv = {'Open': 'first',
           'High': 'max',
           'Low': 'min',
           'Close': 'last',
           'Volume': 'sum'}

df_w = df.resample('W-MON', closed='left', label='left').agg(d_ohlcv)
print(df_w.head())
#               Open    High     Low   Close     Volume
# 2017-01-02  115.80  118.16  114.76  117.91  103845468
# 2017-01-09  117.95  119.93  117.94  119.04  138810760
# 2017-01-16  118.34  120.50  118.22  120.00  116347987
# 2017-01-23  120.00  122.44  119.50  121.95  124748449
# 2017-01-30  120.93  130.49  120.62  129.08  249781248

ダウンサンプリングしたpandas.DataFrameplot()の引数に指定すればよい。

mpf.plot(df_w, type='candle', figratio=(12,4),
         volume=True, mav=(5, 25),
         savefig='data/dst/candlestick_mpf_week.png')

mplfinance plot week

歩み値(ティック)からOHLCを算出する方法や、resample()の詳細などは以下の記事を参照。

月足や年足を作成したい場合はresample()に指定する頻度コードをMSYSなどにすればOK。

この例では元のデータが日足なのでそれより細かい時間足などを作成することはできないが、元のデータが分足であれば、resample()に指定する頻度コードによって30分足(30T)や4時間足(4H)なども作成可能。

[参考] mpl_financeでローソク足チャート(Candlestick chart)を作成

参考までに、以前書いたmpl_financeでローソク足チャート(Candlestick chart)を作成する方法についての説明も残しておく。

上述のようにmpl_financeはDEPRECATEDとなっているので、これから新しいコードを書くならmplfinanceの使用をおすすめする。

なお、バージョン0.12.4a0時点のmplfinanceでは、以下のようにmpl_financeの関数をインポートして使用することもできる。

from mplfinance.original_flavor import candlestick_ohlc

mpl_financeのローソク足チャート用関数

mpl_financeに用意されているローソク足チャート用関数は以下の4つ。

ohlcochlはデータの順序が違い、candlestickcandlestick2はデータの指定方法が違う。

  • candlestick
    • 引数quotestime, open, high, low, closeが列(縦)に並んだ二次元配列を指定
      • 6列目以降はどんなデータが格納されていてもOK
      • timedate2num()で得られる数値(後述)
  • candlestick2
    • 引数opens, highs, lows, closesにそれぞれのデータの一次元配列を指定

以下のサンプルコードではcandlestick_ohlc()を使う。

データ準備

mplfinanceの例と同じく、pandas-datareaderで取得して保存したApple(AAPL)の株価データを例とする。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mpl_finance

df_org = pd.read_csv('data/src/aapl_2015_2019.csv', index_col=0, parse_dates=True)['2017']
print(df_org)
#               open      high      low   close    volume
# 2017-01-03  115.80  116.3300  114.760  116.15  28781865
# 2017-01-04  115.85  116.5100  115.750  116.02  21118116
# 2017-01-05  115.92  116.8642  115.810  116.61  22193587
# 2017-01-06  116.78  118.1600  116.470  117.91  31751900
# 2017-01-09  117.95  119.4300  117.940  118.99  33561948
# ...            ...       ...      ...     ...       ...
# 2017-12-22  174.68  175.4240  174.500  175.01  16052615
# 2017-12-26  170.80  171.4700  169.679  170.57  32968167
# 2017-12-27  170.10  170.7800  169.710  170.60  21672062
# 2017-12-28  171.00  171.8500  170.480  171.08  15997739
# 2017-12-29  170.52  170.5900  169.220  169.23  25643711
# 
# [251 rows x 5 columns]

このpandas.DataFrameから、candlestick_ohlc()の引数quotesに渡す二次元配列numpy.ndarrayを生成する。元データはこのあとも使うのでcopy()で生成したコピーを処理する。

df = df_org.copy()

df.index = mdates.date2num(df.index)
data = df.reset_index().values

matplotlib.datesmdatesとしてインポート)のdate2num()関数でindexの日時データ(numpy.datetime64)を数値に変換する。ここで得られる数値は西暦1年1月1日からの経過日数で、Matplotlibで時系列データを扱う場合に使われるフォーマット。

reset_index()indexを解除(データ列の一番左に移動)して、values属性でpandas.DataFrameからNumPy配列ndarrayを取得する。

以下のような二次元のnumpy.ndarrayが生成できる。

print(type(data))
# <class 'numpy.ndarray'>

print(data.shape)
# (251, 6)

print(data)
# [[7.3633200e+05 1.1580000e+02 1.1633000e+02 1.1476000e+02 1.1615000e+02
#   2.8781865e+07]
#  [7.3633300e+05 1.1585000e+02 1.1651000e+02 1.1575000e+02 1.1602000e+02
#   2.1118116e+07]
#  [7.3633400e+05 1.1592000e+02 1.1686420e+02 1.1581000e+02 1.1661000e+02
#   2.2193587e+07]
#  ...
#  [7.3669000e+05 1.7010000e+02 1.7078000e+02 1.6971000e+02 1.7060000e+02
#   2.1672062e+07]
#  [7.3669100e+05 1.7100000e+02 1.7185000e+02 1.7048000e+02 1.7108000e+02
#   1.5997739e+07]
#  [7.3669200e+05 1.7052000e+02 1.7059000e+02 1.6922000e+02 1.6923000e+02
#   2.5643711e+07]]

グラフ作成

生成した二次元配列numpy.ndarrayは左の列から日時、始値、高値、安値、終値、出来高の順にデータが格納されている。上述の通り、これをcandlestick_ohlc()の第二引数quotesに指定する。6列目の出来高の列は無視される。

fig = plt.figure(figsize=(12, 4))
ax = fig.add_subplot(1, 1, 1)

mpl_finance.candlestick_ohlc(ax, data, width=2, alpha=0.5, colorup='r', colordown='b')

ax.grid()

locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

plt.savefig('data/dst/candlestick_day.png')

plt.close()

引数widthには各ローソクの幅、alphaには透過度、colorupには上昇時の色、colordownには下降時の色をそれぞれ指定する。色はアルファベット一文字や#FFFFFFのようなカラーコードで指定できる。

以下のローソク足チャートが生成される。

pandas matplotlib candlestick chart daily

plt.savefig()ではなくplt.show()とするとグラフが表示される。

以下の3行はX軸の日時をフォーマットするための設定。

locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

AutoDateLocator(), AutoDateFormatter()を使うと自動的に最適な間隔・フォーマットで描画される。MonthLocator()WeekdayLocator()などで任意の間隔を指定したり、%Y%mなどで任意の文字列にフォーマットすることもできる。

fig = plt.figure(figsize=(12, 4))
ax = fig.add_subplot(1, 1, 1)

mpl_finance.candlestick_ohlc(ax, data, width=2, alpha=0.5, colorup='r', colordown='b')

ax.grid()

ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y/%m'))

plt.savefig('data/dst/candlestick_day_format.png')

plt.close()

pandas matplotlib candlestick chart daily format

Matplotlibのバージョン2.0以降はデフォルトで軸の上限・下限に余白ができるようになった。これを変更する設定は以下の記事を参照。

ダウンサンプリング(日足から週足に変換)

週足や月足、年足のチャートを作成したい場合は元のデータをダウンサンプリングする。上述のmplfinanceの例の通り。

d_ohlcv = {'open': 'first',
           'high': 'max',
           'low': 'min',
           'close': 'last',
           'volume': 'sum'}

df_w = df_org.resample('W-MON', closed='left', label='left').agg(d_ohlcv)

あとの流れは日足の場合と同じ。

df_w.index = mdates.date2num(df_w.index)
data_w = df_w.reset_index().values

fig = plt.figure(figsize=(12, 4))
ax = fig.add_subplot(1, 1, 1)

mpl_finance.candlestick_ohlc(ax, data_w, width=4, alpha=0.75, colorup='r', colordown='b')

ax.grid()

locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

plt.savefig('data/dst/candlestick_week.png')

plt.close()

pandas matplotlib candlestick chart weekly

移動平均線

ローソク足チャートと重ねて移動平均線を描画したい場合はrolling()メソッドを使う。

例えば、週次にダウンサンプリングしたpandas.DataFrameの終値(close)の列に対してrolling(n).mean()とするとn週移動平均が算出される。

これを同じaxplot()していく。plot()の第一引数はX軸、第二引数はY軸に相当するデータ列を指定する。

fig = plt.figure(figsize=(12, 4))
ax = fig.add_subplot(1, 1, 1)

mpl_finance.candlestick_ohlc(ax, data_w, width=4, alpha=0.75, colorup='r', colordown='b')
ax.plot(df_w.index, df_w['close'].rolling(4).mean())
ax.plot(df_w.index, df_w['close'].rolling(13).mean())
ax.plot(df_w.index, df_w['close'].rolling(26).mean())

ax.grid()

locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

plt.savefig('data/dst/candlestick_week_sma.png')

plt.close()

pandas matplotlib candlestick chart weekly sma

出来高グラフ(Volume)

OHLCVのV(Volume: 出来高)もあわせて可視化したい場合は、別のサブプロットに棒グラフで描画する。

plt.subplots()nrows, ncolsでサブプロットの行数・列数を指定し、それぞれのaxにグラフを描画する。gridspec_kwで各サブプロットの大きさの比率を指定できる。sharex=TrueとするとX軸が共通化される。

出来高の棒グラフに対してもpandas.DataFrameplot()ではなく、Matplotlibのplot()を使う。

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(12, 4), sharex=True,
                         gridspec_kw={'height_ratios': [3, 1]})

mpl_finance.candlestick_ohlc(axes[0], data_w, width=4, alpha=0.75, colorup='r', colordown='b')

axes[1].bar(df_w.index, df_w['volume'], width=4, color='navy')

axes[0].grid()
axes[1].grid()

locator = mdates.AutoDateLocator()
axes[0].xaxis.set_major_locator(locator)
axes[0].xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

plt.savefig('data/dst/candlestick_week_v.png')

plt.close()

pandas matplotlib candlestick chart weekly volume

移動平均線と出来高グラフの両方を追加する場合もやり方は同じ。

fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(12, 4), sharex=True,
                         gridspec_kw={'height_ratios': [3, 1]})

mpl_finance.candlestick_ohlc(axes[0], data_w, width=4, alpha=0.75, colorup='r', colordown='b')
axes[0].plot(df_w.index, df_w['close'].rolling(4).mean())
axes[0].plot(df_w.index, df_w['close'].rolling(13).mean())
axes[0].plot(df_w.index, df_w['close'].rolling(26).mean())

axes[1].bar(df_w.index, df_w['volume'], width=4, color='navy')

axes[0].grid()
axes[1].grid()

locator = mdates.AutoDateLocator()
axes[0].xaxis.set_major_locator(locator)
axes[0].xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

plt.savefig('data/dst/candlestick_week_sma_v.png')

plt.close()

pandas matplotlib candlestick chart weekly sma volume

関連カテゴリー

関連記事