前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
今回のテーマは「1分足の生成コードを修正する」です。
1分足データを生成するコード(修正版)
今まで使用していたコードでは、接続エラーで止まってしまうことがありました。
そのため、保険的に「接続エラーが出た時にそれを回避する方法」を取り入れました。
今回の修正点は「API接続にエラーが出た際にリトライする」機能を入れたことです。
以下のコードで、bitFlyerのAPIからビットコインFXのローソク足(1分足)を生成することができます。
import requests
import json
from datetime import datetime, timedelta
import time
# APIエンドポイントのURL
api_url = "https://api.bitflyer.com/v1/getexecutions?product_code=FX_BTC_JPY&count=500"
# 最後に保存したtimestampを記録する変数を追加
last_saved_timestamp = None
# ローソク足データを生成する関数
def generate_candlestick_data(executions, timeframe_minutes):
candlestick_data = []
current_candle_start = None
candle = None
for trade in executions:
# APIから取得した日時のフォーマットはミリ秒が含まれているが、無視する
# 日時文字列からミリ秒の部分を取り除く
trade_date = trade['exec_date'].split('.')[0]
timestamp = datetime.strptime(trade_date, "%Y-%m-%dT%H:%M:%S")
# 指定した時間足に基づいてトレードを分類
candle_start = timestamp - timedelta(minutes=timestamp.minute % timeframe_minutes, seconds=timestamp.second)
if candle_start != current_candle_start:
# 新しい足の開始
if candle:
candlestick_data.append(candle)
candle = {
"timestamp": candle_start.strftime("%Y-%m-%dT%H:%M:%S"),
"open": trade["price"],
"high": trade["price"],
"low": trade["price"],
"close": trade["price"],
"volume": trade["size"],
"trades": 1 # 取引回数をカウント
}
current_candle_start = candle_start
else:
# 既存の足にデータを追加
candle["high"] = max(candle["high"], trade["price"])
candle["low"] = min(candle["low"], trade["price"])
candle["close"] = trade["price"]
candle["volume"] += trade["size"]
candle["trades"] += 1 # 取引回数をカウント
# 最後の足を追加
if candle:
candlestick_data.append(candle)
return candlestick_data
# 最大リトライ回数
max_retries = 3
# リトライ間隔(秒)
retry_interval = 5
# 定期的にデータを取得して処理する無限ループ
while True:
retries = 0
while retries < max_retries:
try:
# データ取得
executions = requests.get(api_url).json()
break # 成功した場合はループを抜ける
except Exception as e:
print(f"Error occurred: {e}")
retries += 1
if retries < max_retries:
print(f"Retrying in {retry_interval} seconds...")
time.sleep(retry_interval)
else:
print("Max retries reached. Exiting...")
break
if executions:
# APIから取得したデータを逆順に並び替える
executions.reverse()
# ローソク足データを生成(例: 1分足)
minute_candlestick_data = generate_candlestick_data(executions, timeframe_minutes=1)
# ローソク足データが空でないことを確認
if minute_candlestick_data:
# 最新のtimestampを取得
current_timestamp = datetime.strptime(minute_candlestick_data[-1]['timestamp'], "%Y-%m-%dT%H:%M:%S")
# 最新のtimestampに対応するデータかどうかをチェックし、保存
if current_timestamp != last_saved_timestamp:
with open('minute_candlestick_data.json', 'a') as json_file:
json.dump(minute_candlestick_data[-1], json_file)
json_file.write('\n')
last_saved_timestamp = current_timestamp
print("Candlestick data saved.")
else:
print("No new data to save.")
else:
print("No candlestick data generated.")
else:
print("Failed to fetch data or generate candlestick data.")
# 10秒待機
time.sleep(10)
外部サーバーで12時間以上稼働し続けていました。
約定データがない場合は、ローソク足が生成されないのは今までと同じです。
12時間経過。順調に稼働している。ローソク足データ取得に関しては、とりあえずこれでキリをつける。 pic.twitter.com/uc0sVYMFpp
— よだか(夜鷹/yodaka) (@yodakablog) November 8, 2023
まとめ
ChatGPTを使えば、このコードを元にして5分足・15分足・1時間足・日足のデータ生成も可能です。
現時点で私には必要ないため作成しませんが、今後必要になった時にはこのコードを元に改良していきます。
また、約定履歴からローソク足を生成する仕組み自体は別の取引所でも共通して使うことができます。
今後も一つずつ学習を進めていきます。