CryptoWatchが使えなくなったので、ビットフライヤーの約定履歴からローソク足を作成する。

こんにちは、キテレツえくぼと申します。初めての投稿となります。
9月の上旬にcryptowatchのAPIが有料化されてしまったので、これを機にbitflyerの約定履歴からローソク足を作成しようと考えました。
有料となっていますが、すべて無料で読むことができます。
バックテスト用ではなく、実稼働用のデータを想定しています。

私は学業が本分である大学生でありながら怠惰を極め、学びを放棄している人間であります。さらに大雑把な性格も相まって以下に示すプログラムもおそらく無駄が多く美しさの欠片もないものです。もし、修正点がありましたら是非教えてください。実稼働しているプログラムから該当部分を抜いてきたのでもしかしたら動かないかもしれないです。その時はバグ取りして私に送ってもらえると最高にうれしいです。

では、以下プログラムです。

import requests
from datetime import datetime
from pprint import pprint
import time
import numpy as np
import sys
import pytz
from pytz import timezone
from dateutil import parser
import pandas as pd

chart_sec = 7200             # 使用する時間軸(秒換算)
period = 1600142400          # 開始する時間のtimestamp(>現在時刻のタイムスタンプ)

def utc2jst(utc):
   datestr = str(utc)
   return pytz.timezone('UTC').localize(parser.parse(datestr)).astimezone(timezone('Asia/Tokyo')).strftime("%Y/%m/%d %H:%M:%S")

def get_exe_data() :
   params = dict(product_code="FX_BTC_JPY", count=5) #count <= 500, 最新のデータ1個しか使わないから、count=1でok
   while True :
       try :
           response = requests.get("https://api.bitflyer.com/v1/getexecutions",params=params)
           response.raise_for_status()
           break
       except requests.exceptions.RequestException as e :
           print(e," .. wait 2second ")
           time.sleep(2)
   execution_df = pd.DataFrame(response.json()) #データは0番目が最新
   #最新の約定データの日付と価格を取得
   latest_date = int(datetime.timestamp(datetime.strptime(utc2jst(execution_df["exec_date"][0]),'%Y/%m/%d %H:%M:%S')))
   latest_price = execution_df["price"][0]
   return {"timestp":latest_date, "price":latest_price}

def check_ohlc(last_rt_data,ohlc,period):
   # ローソク足が確定したら、ohlc_flag = True
   if last_rt_data["timestp"] >= period:
       ohlc["close_time"] = last_rt_data["timestp"]
       return True, ohlc
   
   # ローソク足を更新
   if last_rt_data["price"] > ohlc["high_price"]:
       ohlc["high_price"] = last_rt_data["price"]
   if last_rt_data["price"] < ohlc["low_price"]:
       ohlc["low_price"] = last_rt_data["price"]
   ohlc["close_price"] = last_rt_data["price"]
   return False, ohlc


last_data = [] #確定したローソク足を格納
ohlc = {"close_time":0,"open_price":0, "high_price":0, "low_price":0, "close_price":0}
data = {"settled":{# cryptowatch から返されるデータのスタイルに合わせた。
   "close_time":0,
   "open_price":0,
   "high_price":0,
   "low_price":0,
   "close_price":0,
   },
   "forming":{# 形成中のローソク足を格納
   "open_price":0,
   "high_price":0,
   "low_price":0,
   "close_price":0,
   }
   }
ohlc_flag = False #ローソク足が確定したか確認する用のフラグ

#-----開始時間になるまでまつ------ 
while ohlc_flag == False:
   last_rt_data = get_exe_data()
   ohlc_flag,ohlc = check_ohlc(last_rt_data,ohlc,period)
   time.sleep(2)
   if ohlc_flag == True:
       period += chart_sec
       ohlc["open_price"] = last_rt_data["price"]
       ohlc["high_price"] = last_rt_data["price"]
       ohlc["low_price"] = last_rt_data["price"]
       ohlc["close_price"] = last_rt_data["price"]

ohlc_flag = False

#-----MAIN LOOP-------------------------------------
while True:
   last_rt_data = get_exe_data()
   ohlc_flag,ohlc = check_ohlc(last_rt_data,ohlc,period)
   if ohlc_flag == True:
       period += chart_sec
       data["settled"]["close_time"] = last_rt_data["timestp"]
       data["settled"]["open_price"] = ohlc["open_price"]
       data["settled"]["high_price"] = ohlc["high_price"]
       data["settled"]["low_price"] = ohlc["low_price"]
       data["settled"]["close_price"] = ohlc["close_price"]
       data["forming"]["open_price"] = last_rt_data["price"]
       data["forming"]["high_price"] = last_rt_data["price"]
       data["forming"]["low_price"] = last_rt_data["price"]
       data["forming"]["close_price"] = last_rt_data["price"]
       ohlc_flag = False
       ohlc["open_price"] = last_rt_data["price"]
       ohlc["high_price"] = last_rt_data["price"]
       ohlc["low_price"] = last_rt_data["price"]
       ohlc["close_price"] = last_rt_data["price"]
       last_data.append( data["settled"].copy() )
       pprint(last_data)
       time.sleep(2)
       continue
   else:
       data["forming"]["open_price"] = ohlc["open_price"]
       data["forming"]["high_price"] = ohlc["high_price"]
       data["forming"]["low_price"] = ohlc["low_price"]
       data["forming"]["close_price"] = ohlc["close_price"]

プログラムの手順です。
①最新の約定データを指定時間(2秒とか)おきに取り出す
②入手した約定データを用いて、始値、高値、安値、終値を計算
③ローソク足が確定したら、last_dataに格納する。

注意
*bitflyerのAPI は確か5分間に500回だったはずなので、それを超えないようにしてください。
*すべての約定データからローソク足を作成しているわけではなく、2秒おきに入手したデータを使って作成しています。ですので、本来の値より高値は安く、安値は高くなってしまうことがあります。誤差は2時間足では大きい時で本来の値幅より10%ほど小さくなってしまうことがあります。急変時はより大きな誤差が出る可能性があります。max500件を取り出してくれば良いのですが、そうすると私程度の技術では処理に数秒かかってしまい断念しました(pandasよくわからない)。どなたか先駆者様がいましたら教えていただけると嬉しいです。

最後まで読んでいただきありがとうございました。
もし、この記事が役に立ったらジュース代として投げ銭していただけると私がめちゃくちゃ喜びます。

ここから先は

0字

¥ 200

この記事が気に入ったらチップで応援してみませんか?