Python 3 - mpl-finance ローソク足チャートを作成する

目次

休日を考慮したローソク足チャート

休日を考慮したローソク足チャート (candlestick chart) を作成するためには、 mpl_finance モジュールの candlestick_ohlc 関数 (または candlestick_ochl) を使います。

ここで、 candlestick_ohlc 関数の必須な引数は ax, quotes の 2 つです。

オプション引数については、 width, colorup, colordown, alpha が有ります。

Example

source code

import mpl_finance
import numpy

from matplotlib import dates
from matplotlib import pyplot
from datetime import datetime as DateTime
from matplotlib.dates import DateFormatter

def make_mpl_dates(year, month, day):
    return dates.date2num(DateTime(year, month, day))

# time, open, high, low, close, volume
quotes = numpy.array([
    [make_mpl_dates(2019, 1, 14), 90, 105, 85, 100, 1000],
    [make_mpl_dates(2019, 1, 15), 110, 110, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 16), 125, 125, 115, 120, 1200],
    [make_mpl_dates(2019, 1, 17), 120, 140, 120, 140, 1300],
    [make_mpl_dates(2019, 1, 18), 130, 145, 130, 135, 1200],
    [make_mpl_dates(2019, 1, 21), 125, 125, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 22), 115, 120, 90, 105, 900],
    [make_mpl_dates(2019, 1, 23), 110, 115, 100, 110, 1100],
    [make_mpl_dates(2019, 1, 24), 130, 135, 125, 125, 1400],
    [make_mpl_dates(2019, 1, 25), 120, 140, 115, 135, 1500]])

fig = pyplot.figure()
ax = fig.add_subplot(1, 1, 1)

width = 0.25
colorup = "deeppink"
colordown = "blue"
mpl_finance.candlestick_ohlc(ax, quotes, width, colorup, colordown)

ax.xaxis.set_major_formatter(DateFormatter("%Y-%m-%d"))

ax.grid(color="lightgray")
ax.set_axisbelow(True)

fig.autofmt_xdate(rotation=90, ha="center")
pyplot.tight_layout()
pyplot.savefig("candlestick_ohlc.png")

result

実行結果

休日を詰めたローソク足チャート

休日 (及び出来高なしの日) を詰めたローソク足チャート (candlestick chart) を作成するためには、 mpl_finance モジュールの candlestick2_ohlc 関数 (または candlestick2_ochl) を使います。

ここで、 candlestick2_ohlc 関数の必須な引数は ax, opens, highs, lows, closes の 5 つです。

オプション引数については、 width, colorup, colordown, alpha が有ります。

ここで注意点として、 mpl-finance 0.10.0 時点では candlestick2_ohlc, candlestick2_ochl 関数でローソク足を作成する時、 「始値 (open)」と「終値 (close)」が等しい時の色が colordown で指定したものになっています。

気になるようであれば、 終値のそれぞれの値に見た目に影響が出ない程度の数値 (例えば 0.001) を足すことで、 始値と終値が等しい時でも colorup で指定した色にすることができます。

Example

source code

import mpl_finance
import numpy

from matplotlib import dates
from matplotlib import pyplot
from datetime import datetime as DateTime
from matplotlib.ticker import Formatter

class MyIndexDateFormatter(Formatter):
    def __init__(self, times, fmt):
        self.times = times
        self.fmt = fmt

    def __call__(self, x, pos=None):
        index = int(x)
        if index < 0 or index >= len(self.times):
            return ""
        else:
            t = dates.num2date(self.times[index])
            return t.strftime(self.fmt)

def make_mpl_dates(year, month, day):
    return dates.date2num(DateTime(year, month, day))

# time, open, high, low, close, volume
quotes = numpy.array([
    [make_mpl_dates(2019, 1, 14), 90, 105, 85, 100, 1000],
    [make_mpl_dates(2019, 1, 15), 110, 110, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 16), 125, 125, 115, 120, 1200],
    [make_mpl_dates(2019, 1, 17), 120, 140, 120, 140, 1300],
    [make_mpl_dates(2019, 1, 18), 130, 145, 130, 135, 1200],
    [make_mpl_dates(2019, 1, 21), 125, 125, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 22), 115, 120, 90, 105, 900],
    [make_mpl_dates(2019, 1, 23), 110, 115, 100, 110, 1100],
    [make_mpl_dates(2019, 1, 24), 130, 135, 125, 125, 1400],
    [make_mpl_dates(2019, 1, 25), 120, 140, 115, 135, 1500]])

times = quotes[:, 0]
opens = quotes[:, 1]
highs = quotes[:, 2]
lows = quotes[:, 3]
closes = quotes[:, 4]

fig = pyplot.figure()
ax = fig.add_subplot(1, 1, 1)

width = 0.25
colorup = "deeppink"
colordown = "blue"
mpl_finance.candlestick2_ohlc(ax,
                              opens,
                              highs,
                              lows,
                              closes,
                              # closes + 0.001,
                              width,
                              colorup,
                              colordown)

formatter = MyIndexDateFormatter(times, "%Y-%m-%d")
ax.xaxis.set_major_formatter(formatter)

ax.grid(color="lightgray")
ax.set_axisbelow(True)

fig.autofmt_xdate(rotation=90, ha="center")
pyplot.tight_layout()
pyplot.savefig("candlestick2_ohlc.png")

result

実行結果

陽線を白抜きにする

mpl_finance ライブラリの関数を利用して陽線を白抜きにしたい場合は、 次のような手順などで実現することができます。

  1. まず、colorupcolordown は異なる色とする (もし両方とも同じ色、 例えば黒にしたい場合は、 それぞれ #000001#000000 などを指定します)
  2. candlestick2_ohlc 関数の戻り値である「タプル (LineCollection, PolyCollection)」を取得する
  3. PolyCollection オブジェクトの get_facecolors メソッドで、 facecolor の二次元配列を取得する
  4. 二次元配列を行ごとにループして、 任意の行と colorup が等しければ、その行の色をグラフの背景色に設定する
  5. もし、矩形の前面にヒゲが描画される場合は、 PolyCollection オブジェクトの set_zorder メソッドで描画される順序を調整する

Example

source code

import mpl_finance
import numpy

from matplotlib import colors
from matplotlib import dates
from matplotlib import pyplot
from datetime import datetime as DateTime
from matplotlib.ticker import Formatter

class MyIndexDateFormatter(Formatter):
    def __init__(self, times, fmt):
        self.times = times
        self.fmt = fmt

    def __call__(self, x, pos=None):
        index = int(x)
        if index < 0 or index >= len(self.times):
            return ""
        else:
            t = dates.num2date(self.times[index])
            return t.strftime(self.fmt)

def make_mpl_dates(year, month, day):
    return dates.date2num(DateTime(year, month, day))

# time, open, high, low, close, volume
quotes = numpy.array([
    [make_mpl_dates(2019, 1, 14), 90, 105, 85, 100, 1000],
    [make_mpl_dates(2019, 1, 15), 110, 110, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 16), 125, 125, 115, 120, 1200],
    [make_mpl_dates(2019, 1, 17), 120, 140, 120, 140, 1300],
    [make_mpl_dates(2019, 1, 18), 130, 145, 130, 135, 1200],
    [make_mpl_dates(2019, 1, 21), 125, 125, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 22), 115, 120, 90, 105, 900],
    [make_mpl_dates(2019, 1, 23), 110, 115, 100, 110, 1100],
    [make_mpl_dates(2019, 1, 24), 130, 135, 125, 125, 1400],
    [make_mpl_dates(2019, 1, 25), 120, 140, 115, 135, 1500]])

times = quotes[:, 0]
opens = quotes[:, 1]
highs = quotes[:, 2]
lows = quotes[:, 3]
closes = quotes[:, 4]

fig = pyplot.figure()
ax = fig.add_subplot(1, 1, 1)

width = 0.25
colorup = "#000001"
colordown = "#000000"
(cnd_lc, cnd_pc) = mpl_finance.candlestick2_ohlc(ax,
                                                 opens,
                                                 highs,
                                                 lows,
                                                 closes,
                                                 width,
                                                 colorup,
                                                 colordown,
                                                 1.0)
colorup_array = numpy.array(colors.to_rgba(colorup))
fcs = cnd_pc.get_facecolors()
for (i, c) in enumerate(fcs):
    if (c == colorup_array).all():
        fcs[i] = ax.get_facecolor()
cnd_pc.set_zorder(10)

formatter = MyIndexDateFormatter(times, "%Y-%m-%d")
ax.xaxis.set_major_formatter(formatter)

ax.grid(color="lightgray")
ax.set_axisbelow(True)

fig.autofmt_xdate(rotation=90, ha="center")
pyplot.tight_layout()
pyplot.savefig("candlestick_chart_outline.png")

result

実行結果

ヒゲの書式を変更する

mpl_finance ライブラリの関数を利用してヒゲの書式を変更したい場合は、 次のような手順などで実現することができます。

  1. candlestick2_ohlc 関数の戻り値である「タプル (LineCollection, PolyCollection)」を取得する
  2. LineCollection オブジェクトの set_linewidth メソッドでヒゲの太さを変更することができる
  3. LineCollection オブジェクトの set_edgecolor メソッドでヒゲの色を変更することができる
  4. PolyCollection オブジェクトの set_linewidth メソッドで矩形の枠線の太さを変更することができる
  5. PolyCollection オブジェクトの set_edgecolor メソッドで矩形の枠線の色を変更することができる
  6. もし、矩形の前面にヒゲが描画される場合は、 PolyCollection オブジェクトの set_zorder メソッドで描画される順序を調整する

Example

source code

import mpl_finance
import numpy

from matplotlib import dates
from matplotlib import pyplot
from datetime import datetime as DateTime
from matplotlib.ticker import Formatter

class MyIndexDateFormatter(Formatter):
    def __init__(self, times, fmt):
        self.times = times
        self.fmt = fmt

    def __call__(self, x, pos=None):
        index = int(x)
        if index < 0 or index >= len(self.times):
            return ""
        else:
            t = dates.num2date(self.times[index])
            return t.strftime(self.fmt)

def make_mpl_dates(year, month, day):
    return dates.date2num(DateTime(year, month, day))

# time, open, high, low, close, volume
quotes = numpy.array([
    [make_mpl_dates(2019, 1, 14), 90, 105, 85, 100, 1000],
    [make_mpl_dates(2019, 1, 15), 110, 110, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 16), 125, 125, 115, 120, 1200],
    [make_mpl_dates(2019, 1, 17), 120, 140, 120, 140, 1300],
    [make_mpl_dates(2019, 1, 18), 130, 145, 130, 135, 1200],
    [make_mpl_dates(2019, 1, 21), 125, 125, 110, 110, 1100],
    [make_mpl_dates(2019, 1, 22), 115, 120, 90, 105, 900],
    [make_mpl_dates(2019, 1, 23), 110, 115, 100, 110, 1100],
    [make_mpl_dates(2019, 1, 24), 130, 135, 125, 125, 1400],
    [make_mpl_dates(2019, 1, 25), 120, 140, 115, 135, 1500]])

times = quotes[:, 0]
opens = quotes[:, 1]
highs = quotes[:, 2]
lows = quotes[:, 3]
closes = quotes[:, 4]

fig = pyplot.figure()
ax = fig.add_subplot(1, 1, 1)

width = 0.25
colorup = "pink"
colordown = "cyan"
(cnd_lc, cnd_pc) = mpl_finance.candlestick2_ohlc(ax,
                                                 opens,
                                                 highs,
                                                 lows,
                                                 closes,
                                                 width,
                                                 colorup,
                                                 colordown,
                                                 1.0)
cnd_lc.set_linewidth(0.75)
cnd_lc.set_edgecolor("black")
cnd_pc.set_linewidth(0.75)
cnd_pc.set_edgecolor("black")
cnd_pc.set_zorder(10)

formatter = MyIndexDateFormatter(times, "%Y-%m-%d")
ax.xaxis.set_major_formatter(formatter)

ax.grid(color="lightgray")
ax.set_axisbelow(True)

fig.autofmt_xdate(rotation=90, ha="center")
pyplot.tight_layout()
pyplot.savefig("candlestick_chart_tails_format.png")

result

実行結果

参考リンク