BybitAPIでローソク足データを取得する
勉強記録⑰のリファインです。
なんと、この関数を使っているとの声を頂いたので、せっかくなので修正することにしました。
⑰を修正してもよかったけど、成長を感じたいので別の記事にしましたッ
◆コード
# -*- coding: utf-8 -*-
"""
Created on Thu May 6 22:40:08 2021
@author: Mamu
"""
from tqdm import tqdm
from datetime import datetime,timedelta,timezone
import pybybit
import pandas as pd
import json
#--------------------設定項目--------------------
apis = [
'API',
'シークレット'
]
bybit = pybybit.API(*apis, testnet = True)
symbol = "BTCUSD"
chart_min = 1 # 時間軸(1 3 5 15 30 60 120 240 360 720 "D" "W" "M" )
get_start = '2019/06/01 09:00' # ローソク足取得開始時刻
#--------------------関数--------------------
#====================価格データ取得===================
def get_price(chart_min,start):
get_start = int(datetime.strptime(start,'%Y/%m/%d %H:%M').timestamp()) # タイムスタンプ変換
price = []
#200*n本のローソク足を取得して、price[]に入れる
for o in tqdm(range(30), desc="{}分足データ取得中".format(chart_min)): # ()内の回数だけデータを取得
#pybybitでローソク足取得
data = bybit.rest.inverse.public_kline_list(
symbol = symbol,
interval = chart_min,
from_ = get_start
).json()
#priceに取得したデータを入れる
#bybitから帰ってくるデータがstr型なので、float型に変換してから格納する
for i in data["result"]:
price.append({
"open_time" :i["open_time"],
"open" :float(i["open"]),
"high" :float(i["high"]),
"low" :float(i["low"]),
"close" :float(i["close"]),
"volume" :float(i["volume"])
})
#200本x足の長さ分だけタイムスタンプを進める
if chart_min == "D" :
get_start += 200*60*1440
elif chart_min == "W" :
get_start += 200*60*10080
else:
get_start += 200*60*chart_min
return price
#====================DF作成===================
def cleate_table(data):
df = pd.DataFrame(data)
# 世界協定時から日本標準時を算出
tz_jst = timezone(timedelta(hours=+9), name='JST')
# dfのopen_timeを日本時間にして表示(UTCのままでいい場合は不要)
df['open_time'] = (df['open_time'].apply(lambda x : datetime.fromtimestamp(x, tz_jst).strftime('%Y/%m/%d %H:%M')))
print(df)
return df
#====================ファイル出力===================
def output_file( data,df ):
# 表をCSVで出力
df.to_csv("./{0}min-{1}-{2}.csv".format(chart_min,data[0]["open_time"],data[-1]["open_time"]))
# ローソク足をjsonファイルで出力
file = open("./{0}min-{1}-{2}.json".format(chart_min,data[0]["open_time"],data[-1]["open_time"]),"w",encoding="utf-8")
json.dump(data,file,indent=4)
#--------------------メイン処理--------------------
data = get_price(chart_min,get_start)
df = cleate_table(data)
# output_file( data,df )
◆解説
3つの関数を作っています。
いつものごとくPybybitを使います。
・get_price(chart_min,start)
#====================価格データ取得===================
def get_price(chart_min,start):
get_start = int(datetime.strptime(start,'%Y/%m/%d %H:%M').timestamp()) # タイムスタンプ変換
price = []
#200*n本のローソク足を取得して、price[]に入れる
for o in tqdm(range(30), desc="{}分足データ取得中".format(chart_min)): # ()内の回数だけデータを取得
#pybybitでローソク足取得
data = bybit.rest.inverse.public_kline_list(
symbol = symbol,
interval = chart_min,
from_ = get_start
).json()
#priceに取得したデータを入れる
#bybitから帰ってくるデータがstr型なので、float型に変換してから格納する
for i in data["result"]:
price.append({
"open_time" :i["open_time"],
"open" :float(i["open"]),
"high" :float(i["high"]),
"low" :float(i["low"]),
"close" :float(i["close"]),
"volume" :float(i["volume"])
})
#200本x足の長さ分だけタイムスタンプを進める
if chart_min == "D" :
get_start += 200*60*1440
elif chart_min == "W" :
get_start += 200*60*10080
else:
get_start += 200*60*chart_min
return price
指定した回数だけBybitへのローソク足取得リクエストを送る関数です。
BybitののAPIでは、ローソク足は1回のリクエストで最大200本しかデータを返してくれないので、何度もリクエストを送ることで多くのデータを取得します。
また、Bybitから帰ってくるデータは大体str型です、、、なんでやねん
そのため、使いやすいように取得の際にfloat型に変換しています。
また、tqdmというライブラリでデータの取得状況を確認できるようにしました。いい感じです!
・cleate_table(data)
#====================DF作成===================
def cleate_table(data):
df = pd.DataFrame(data)
# 世界協定時から日本標準時を算出
tz_jst = timezone(timedelta(hours=+9), name='JST')
# dfのopen_timeを日本時間にして表示(UTCのままでいい場合は不要)
df['open_time'] = (df['open_time'].apply(lambda x : datetime.fromtimestamp(x, tz_jst).strftime('%Y/%m/%d %H:%M')))
print(df)
return df
PandasDataFrameを作る関数です。
取得したローソク足データをDataFrameにします。
DataFrameではopen_timeをタイムスタンプから日本時間表示に変更していますが、いらなければコメントアウトしてください。
・output_file( data,df )
#====================ファイル出力===================
def output_file( data,df ):
# 表をCSVで出力
df.to_csv("./{0}min-{1}-{2}.csv".format(chart_min,data[0]["open_time"],data[-1]["open_time"]))
# ローソク足をjsonファイルで出力
file = open("./{0}min-{1}-{2}.json".format(chart_min,data[0]["open_time"],data[-1]["open_time"]),"w",encoding="utf-8")
json.dump(data,file,indent=4)
作成したDFをcsv形式、ローソク足データをjson形式にして出力する関数です。出力先を変更したい場合は、"./{0}min-{1}-{2}.csv"の部分に出力先の絶対パスを入れれば変更できます。
(./の部分が実行ファイルと同じ場所を指しています。)
◆実行結果
GIF貼りたかった。。。
実行中にバーがどんどん伸びていって楽しいです。
runfile('C:/Pydoc/get_price.py', wdir='C:/Pydoc')
1分足データ取得中: 100%|██████████| 30/30 [00:09<00:00, 3.01it/s]
open_time open high low close volume
0 2019/06/01 09:00 8550.0 8555.5 8544.5 8545.5 92286.0
1 2019/06/01 09:01 8545.5 8564.0 8545.0 8558.0 229509.0
2 2019/06/01 09:02 8558.0 8567.0 8557.0 8567.0 88257.0
3 2019/06/01 09:03 8567.0 8567.0 8558.0 8564.5 138781.0
4 2019/06/01 09:04 8564.5 8564.5 8558.5 8558.5 78892.0
... ... ... ... ... ...
5995 2019/06/05 12:55 7798.0 7798.0 7796.5 7796.5 354058.0
5996 2019/06/05 12:56 7796.5 7797.0 7792.0 7792.5 71034.0
5997 2019/06/05 12:57 7792.5 7792.5 7786.0 7786.0 56066.0
5998 2019/06/05 12:58 7786.0 7792.0 7785.5 7791.5 152173.0
5999 2019/06/05 12:59 7791.5 7796.5 7791.5 7794.5 90425.0
[6000 rows x 6 columns]
デフォルトではリクエスト回数を30にしているので、6,000個のデータを取得できます。
リクエスト回数を300にすれば、60,000個のデータを取得できます(時間かかります)
runfile('C:/Pydoc/get_price.py', wdir='C:/Pydoc')
1分足データ取得中: 100%|██████████| 300/300 [01:48<00:00, 2.77it/s]
open_time open high low close volume
0 2019/06/01 09:00 8550.0 8555.5 8544.5 8545.5 92286.0
1 2019/06/01 09:01 8545.5 8564.0 8545.0 8558.0 229509.0
2 2019/06/01 09:02 8558.0 8567.0 8557.0 8567.0 88257.0
3 2019/06/01 09:03 8567.0 8567.0 8558.0 8564.5 138781.0
4 2019/06/01 09:04 8564.5 8564.5 8558.5 8558.5 78892.0
... ... ... ... ... ...
59995 2019/07/13 00:55 11537.0 11542.5 11537.0 11542.5 26883.0
59996 2019/07/13 00:56 11542.5 11562.0 11542.5 11562.0 30061.0
59997 2019/07/13 00:57 11562.0 11567.5 11551.0 11551.0 71350.0
59998 2019/07/13 00:58 11551.0 11551.5 11545.0 11545.0 170529.0
59999 2019/07/13 00:59 11545.0 11545.0 11528.5 11529.5 44854.0
[60000 rows x 6 columns]
おわり