ビットコインの日足チャートをPythonとPlotlyでプロットしてみた

今回はPythonとPlotlyを使ってビットコインの日足チャートをプロットする方法についてまとめていきます。

ちなみにRバージョンも書いてみたのでRユーザーはこちらを覗いて見てください。

ビットコインの日足チャートをRとPlotlyでプロットしてみた

データ取得

ローソク足のデータはCryptowatのAPIを使って取得します。

取得の方法についての詳細はAPIドキュメントを参照してください。

import requests
import json
import pandas as pd

# Bitflyerの円建てBTC価格を取得
res = requests.get('https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc')
data = json.loads(res.text)
# resultの下にある「86400」のキーが日足データ
daily_data = pd.DataFrame(data['result']['86400'], columns=['close_time', 'open_price', 'high_price', 'low_price', 'close_price', 'volume', 'quote_volume'])
daily_data.head()
 close_time open_price high_price low_price close_price volume quote_volume
0 1435276800 29020 32000 29020 32000 0.033 0.0
1 1435363200 32000 31700 31700 31700 0.001 0.0
2 1435449600 31700 31704 30550 31000 2.739 0.0
3 1435536000 31000 31220 30870 30870 1.280 0.0
4 1435622400 30870 31550 30900 31550 0.990 0.0

close_timeがタイムスタンプなので「YYYY-MM-DD」の形式に変換します。

ここでは新しくdateというカラムに変換後の日付を入れます。

daily_data['date'] = pd.to_datetime(daily_data['close_time'], unit='s')
daily_data.head()
 close_time open_price high_price low_price close_price volume quote_volume date
0 1435276800 29020 32000 29020 32000 0.033 0.0 2015-06-26
1 1435363200 32000 31700 31700 31700 0.001 0.0 2015-06-27
2 1435449600 31700 31704 30550 31000 2.739 0.0 2015-06-28
3 1435536000 31000 31220 30870 30870 1.280 0.0 2015-06-29
4 1435622400 30870 31550 30900 31550 0.990 0.0 2015-06-30

ローソク足のプロット

ここからは先程のデータを使ってPlotlyでローソク足をプロットしていきます。

from plotly.graph_objs import *
trace1 = {
    'type': 'candlestick',
    'x': daily_data['date'],
    'yaxis': 'y2',
    'low': daily_data['low_price'],
    'high': daily_data['high_price'],
    'open': daily_data['open_price'],
    'close': daily_data['close_price'],
}
fig = Figure(data=[trace1])
fig.show()

結構簡単にプロットできました。

上のやつはキャプチャですが、実際にプロットした場合はグリグリ動かせるかと思います。

移動平均線のプロット

ついでに移動平均線のプロットもやってみたいと思います。

まずは以下のように移動平均を計算しましょう。今回は直近20日の平均を算出します。(20MA)

daily_data['20ma'] = daily_data['close_price'].rolling(10).mean()
daily_data.tail()
>>> daily_data.tail()
close_time open_price high_price low_price close_price volume quote_volume date 20ma
2057 1613088000 4705847 5085000 4612000 5014707 9617.179887 4.692349e+10 2021-02-12 4327996.2
2058 1613174400 5013546 5102000 4863114 4973709 7185.807918 3.588426e+10 2021-02-13 4454105.2
2059 1613260800 4972983 5047330 4900475 4957394 4297.797821 2.137934e+10 2021-02-14 4556564.8
2060 1613347200 4956639 5197101 4944896 5111984 6926.060459 3.534680e+10 2021-02-15 4677600.8
2061 1613433600 5111984 5154000 5090009 5103424 377.511544 1.934551e+09 2021-02-16 4784362.0

移動平均の算出ができたら、先程のローソク足に加え、移動平均のグラフを同時にプロットします。

race1 = {
    'type': 'candlestick', 
    'x': daily_data['date'], 
    'yaxis': "y2",
    'low': daily_data['low_price'], 
    'high': daily_data['high_price'], 
    'open': daily_data['open_price'], 
    'close': daily_data['close_price']
}
trace2 = {
    'line': {'width': 1}, 
    'mode': 'lines', 
    'name': '20MA', 
    'type': 'scatter', 
    'x': daily_data['date'], 
    'y': daily_data['20ma'], 
    'yaxis': 'y2', 
    'marker': {'color': '#E377C2'}
}
fig = Figure(data=[trace1, trace2])
fig.show()

上記の例では20MAを一本引いただけですが、traceを増やすことで50MAや100MAを同時にプロットすることも可能なので気になる方はやってみてください。

ボリンジャーバンドのプロット

最後にボリンジャーバンドのプロットもやってみましょう。

以下のようにボリンジャーバンドの線を計算します。(※ここではボリンジャーバンドの詳細は省きます)

daily_data['bb_mean'] = daily_data['close_price'].rolling(window=20).mean()
daily_data['bb_std'] = daily_data['close_price'].rolling(window=20).std()
daily_data['bb_upper'] = daily_data['bb_mean'] + (daily_data['bb_std'] * 2)
daily_data['bb_lower'] = daily_data['bb_mean'] - (daily_data['bb_std'] * 2)
daily_data.tail()
>>> daily_data.tail()
close_time open_price high_price low_price close_price volume quote_volume date 20ma bb_mean bb_std bb_upper bb_lower
2057 1613088000 4705847 5085000 4612000 5014707 9617.179887 4.692349e+10 2021-02-12 4327996.2 3871322.00 581227.211074 5.033776e+06 2.708868e+06
2058 1613174400 5013546 5102000 4863114 4973709 7185.807918 3.588426e+10 2021-02-13 4454105.2 3953401.25 615948.515275 5.185298e+06 2.721504e+06
2059 1613260800 4972983 5047330 4900475 4957394 4297.797821 2.137934e+10 2021-02-14 4556564.8 4033749.75 637584.303813 5.308918e+06 2.758581e+06
2060 1613347200 4956639 5197101 4944896 5111984 6926.060459 3.534680e+10 2021-02-15 4677600.8 4121654.65 659728.416824 5.441111e+06 2.802198e+06
2061 1613433600 5111984 5154000 5090009 5103424 377.511544 1.934551e+09 2021-02-16 4784362.0 4208626.75 669175.076761 5.546977e+06 2.870277e+06

算出できたら以下のようにプロットします。(冗長なコードですが一旦気にしない・・・)

基本的にプロットのやり方は移動平均線と同じです。

trace1 = {
    'type': 'candlestick', 
    'x': daily_data['date'], 
    'yaxis': "y2",
    'low': daily_data['low_price'], 
    'high': daily_data['high_price'], 
    'open': daily_data['open_price'], 
    'close': daily_data['close_price']
}
trace2 = {
    'line': {'width': 1}, 
    'mode': 'lines', 
    'name': 'BB MEAN', 
    'type': 'scatter', 
    'x': daily_data['date'], 
    'y': daily_data['bb_mean'], 
    'yaxis': 'y2', 
    'marker': {'color': '#E377C2'}
}
trace3 = {
    'line': {'width': 1}, 
    'mode': 'lines', 
    'name': 'B Bands', 
    'type': 'scatter', 
    'x': daily_data['date'], 
    'y': daily_data['bb_upper'], 
    'yaxis': 'y2', 
    'marker': {'color': '#CCC'},
    'legendgroup': 'BB', 
}
trace4 = {
    'line': {'width': 1}, 
    'mode': 'lines', 
    'name': 'B Bands', 
    'type': 'scatter', 
    'x': daily_data['date'], 
    'y': daily_data['bb_lower'], 
    'yaxis': 'y2', 
    'marker': {'color': '#CCC'},
    'legendgroup': 'BB', 
}
fig = Figure(data=[trace1, trace2, trace3, trace4])
fig.show()

「B Bands」の凡例が重複してしまったけどまぁいっか・・・