2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでCandlestickChartをBokehで描けるようになるまで

Posted at

きっかけ

 Botterになるためにまずはチャートを描けるようにならなくてはいけないと思いました。
 最初、Plotlyでやってたんだけど、有料っていうのを見かけたので、Bokehにシフト

環境

  • Windows 10 Pro 21H1
  • Python 3.9.7
  • Jupyter Notebook 6.4.5
  • Pandas 1.3.4
  • Bokeh 2.4.1

コード

from math import pi

import pandas as pd

from bokeh.plotting import figure, show, output_file
from bokeh.sampledata.stocks import MSFT

df = pd.DataFrame(MSFT)
df["date"] = pd.to_datetime(df["date"])

mids = (df.open + df.close)/2
spans = abs(df.close-df.open)

inc = df.close > df.open
dec = ~inc


# 日時表示用のフォーマットを設定(日足と分足に分岐
xaxis_dt_format = '%Y-%m-%d'
if df.iloc[0]['date'].hour > 0:
    xaxis_dt_format = '%Y-%m-%d_%H:%M:%S'


# チャートの初期設定
p = figure(sizing_mode="stretch_both",
           tools=TOOLS, 
           x_axis_type="linear", # linearを指定しないと、土日が空くチャートになる。
           plot_width=1000, 
           toolbar_location="left")


# Colour scheme for increasing and descending candles
# 色はなんとなくTradingViewに合わせた
INCREASING_COLOR = '#26a69a'
DECREASING_COLOR = '#ef5350'

width = 0.5
# 陽線と陰線のデータをまとめちゃう
inc_source = ColumnDataSource(data=dict(
    x1=df.index[inc],
    top1=df.open[inc],
    bottom1=df.close[inc],
    high1=df.high[inc],
    low1=df.low[inc],
    Date1=df.date[inc]
))

dec_source = ColumnDataSource(data=dict(
    x2=df.index[dec],
    top2=df.open[dec],
    bottom2=df.close[dec],
    high2=df.high[dec],
    low2=df.low[dec],
    Date2=df.date[dec]
))

w = 12*60*60*1000 # half day in ms 半日をミリ秒に?

TOOLS = "pan,wheel_zoom,box_zoom,crosshair,reset,save"


p.title = "MSFT Candlestick"
p.xaxis.major_label_orientation = pi/4 # X軸のラベルを開店
p.grid.grid_line_alpha=0.3
p.yaxis[0].formatter = NumeralTickFormatter(format="5.3f") # y軸のフォーマット

# Plot candles #ローソク足を描いていく
# High and low
p.segment(x0='x1', y0='high1', x1='x1', y1='low1', source=inc_source, color=INCREASING_COLOR)
p.segment(x0='x2', y0='high2', x1='x2', y1='low2', source=dec_source, color=DECREASING_COLOR)

# Open and close
r1 = p.vbar(x='x1', width=width, top='top1', bottom='bottom1', source=inc_source,
                fill_color=INCREASING_COLOR, line_color=INCREASING_COLOR)
r2 = p.vbar(x='x2', width=width, top='top2', bottom='bottom2', source=dec_source,
                fill_color=DECREASING_COLOR, line_color=DECREASING_COLOR)
# Add date labels to x axis
p.xaxis.major_label_overrides = {
    i: date.strftime(xaxis_dt_format) for i, date in enumerate(pd.to_datetime(df.date))
}

# Set up the hover tooltip to display some useful data
p.add_tools(HoverTool(
    renderers=[r1],
    tooltips=[
        ("Open", "$@top1"),
        ("High", "$@high1"),
        ("Low", "$@low1"),
        ("Close", "$@bottom1"),
        ("Date", "@Date1{" + xaxis_dt_format + "}"),
    ],
    formatters={
        '@Date1': 'datetime',
        
    },
    mode='vline', # 縦線に相当する値を表示
    # mode='mouse',  # マウスポインタを合わせたときに表示
))

p.add_tools(HoverTool(
    renderers=[r2],
    tooltips=[
        ("Open", "$@top2"),
        ("High", "$@high2"),
        ("Low", "$@low2"),
        ("Close", "$@bottom2"),
        ("Date", "@Date2{" + xaxis_dt_format + "}")
    ],
    formatters={
        '@Date2': 'datetime',
    },
    mode='vline', # 縦線に相当する値を表示
    # mode='mouse',  # マウスポインタを合わせたときに表示
))
#output_file("candlestick.html", title="candlestick.py example")

# 出力先をノートブックに設定
output_notebook() 

show(p)  # open a browser

結果

スクリーンショット (5).png

補足

bokeh.sampledata.stocksは、事前にダウンロードしないといけないです。
下記を事前に実行しておくと、データ落としといてくれます。

import bokeh.sampledata
bokeh.sampledata.download()

今後の予定

移動平均線とか出してみたいと思っている。

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?