note.nkmk.me

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

Date: 2018-08-29 / tags: Python, pandas, Matplotlib, 時系列データ

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

  • matplotlib.financeとmpl_finance
    • mpl_financeのインストール
  • ローソク足チャート(Candlestick chart)を作成
    • mpl_financeのローソク足チャート用関数
    • サンプルデータの取得
    • ローソク足チャート作成のサンプルコード
  • ダウンサンプリング: 日足から週足に変換
  • 移動平均線追加
  • 出来高グラフを追加

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

スポンサーリンク

matplotlib.financeとmpl_finance

ローソク足チャートの作成にはmpl_financeモジュールを使う。

以前はmatplotlib.financeとしてMatplotlibに含まれていたが、バージョン2.0からはmpl_financeモジュールとして切り出された。ドキュメントは以下のMatplotlibの公式サイトに残されている。

mpl_financeのインストール

mpl_financeはMatplotlibとは別にインストールする必要がある。

以前はGitHubからインストールする必要があったが、2018年8月29日現在はpip(またはpip3)で直接インストールできるようになっている。バージョンは0.10.0

$ pip install mpl_finance

もしもインストールできなくなっていたら以下のようにGitHubからインストールできる。

$ pip install git+https://github.com/matplotlib/mpl_finance.git

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

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

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

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

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

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

サンプルデータの取得

ここではpandas-datareaderで2017年のAppleの株価データを取得して例とする。

2018年8月29日現在、pandasとpandas-datareaderのバージョンによってはインポートエラーが発生するので注意。その対処法ほか、pandas-datareaderについての詳細は以下の記事を参照。

日次のOHLCVデータが取得できる。インデックスは文字列なのでpd.to_datetime()で変換する。

import pandas as pd
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mpl_finance

df = web.DataReader('AAPL', 'iex', '2017-01-01', '2017-12-31')

df.index = pd.to_datetime(df.index)

print(df.shape)
# (251, 5)

print(df.head())
#                 open      high       low     close    volume
# date                                                        
# 2017-01-03  112.6732  113.1889  111.6613  113.0138  28781865
# 2017-01-04  112.7219  113.3641  112.6246  112.8873  21118116
# 2017-01-05  112.7900  113.7087  112.6830  113.4614  22193587
# 2017-01-06  113.6268  114.9695  113.3251  114.7263  31751900
# 2017-01-09  114.7652  116.2052  114.7554  115.7771  33561948

print(df.tail())
#                 open      high       low     close    volume
# date                                                        
# 2017-12-22  172.6967  173.4323  172.5188  173.0230  16349444
# 2017-12-26  168.8608  169.5232  167.7525  168.6334  33185536
# 2017-12-27  168.1687  168.8410  167.7831  168.6630  21498213
# 2017-12-28  169.0585  169.8988  168.5444  169.1376  16480187
# 2017-12-29  168.5839  168.6531  167.2987  167.3086  25999922

ローソク足チャート作成のサンプルコード

引数quotesに渡す二次元配列を生成する。

df_ = df.copy()

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

元データはこのあとも使うのでcopy()で生成したコピーを処理する。

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

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

以下のような二次元配列(numpy.ndarray)となる。

print(data)
# [[7.3633200e+05 1.1267320e+02 1.1318890e+02 1.1166130e+02 1.1301380e+02
#   2.8781865e+07]
#  [7.3633300e+05 1.1272190e+02 1.1336410e+02 1.1262460e+02 1.1288730e+02
#   2.1118116e+07]
#  [7.3633400e+05 1.1279000e+02 1.1370870e+02 1.1268300e+02 1.1346140e+02
#   2.2193587e+07]
#  ...
#  [7.3669000e+05 1.6816870e+02 1.6884100e+02 1.6778310e+02 1.6866300e+02
#   2.1498213e+07]
#  [7.3669100e+05 1.6905850e+02 1.6989880e+02 1.6854440e+02 1.6913760e+02
#   1.6480187e+07]
#  [7.3669200e+05 1.6858390e+02 1.6865310e+02 1.6729870e+02 1.6730860e+02
#   2.5999922e+07]]

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

左の列から日時、始値、高値、安値、終値、出来高の順にデータが格納されている。最初の5列がtime, open, high, low, closeとなっているので、上述の通り、これを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')

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

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

pandas matplotlib candlestick chart daily

以下の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')

pandas matplotlib candlestick chart daily format

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

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

pandas-datareaderで取得できるのは日次のOHLCVデータなので、そのままローソク足チャートを作成すると上の例のように日足のチャートになる。

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

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).copy()

OHLCVデータのダウンサンプリングにはresample()メソッドを使う。詳細は以下の記事を参照。

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

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')

pandas matplotlib candlestick chart weekly

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

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

移動平均線追加

ローソク足チャートと重ねて移動平均線を描画したい場合は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')

pandas matplotlib candlestick chart weekly sma

出来高グラフを追加

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')

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')

pandas matplotlib candlestick chart weekly sma volume

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事