前回の記事に引き続き、今回も仮想通貨ボットの開発状況をまとめていきます。
以前より、生成したローソク足データの読み込みでエラーが出ていたので、その原因を突き止めようとしています。
結論としては、データが整理されていないことが原因だったようです。
コードを修正して1分足のデータを保存・更新するようにしました。
ローソク足データ(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
# 定期的にデータを取得して処理する無限ループ
while True:
# データ取得
executions = requests.get(api_url).json()
if executions:
# ローソク足データを生成(例: 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)
実行結果は以下の通り。

時々、抜け漏れがありますね。
ひどい時には10分以上も間隔が空いています。
この状態では、完全な1分足データの獲得には至りません。
しかも、稼働から7時間ほど経ったら止まっていました...。
エラーの原因と修正が必要ですね。

1分足データの生成と読み込み
上記のコードで生成された1分足データは以下のコードで読み込みおよび書き出しができます。
import json
# ファイルパス
file_path = 'ここにファイルパス名を入力'
# JSONファイルを読み込んでデータを取得
with open(file_path, 'r') as file:
data = file.readlines()
# 読み込んだデータを出力
for line in data:
# 各行のJSON文字列をパースして辞書に変換
candlestick_data = json.loads(line)
# 辞書を出力
print(candlestick_data)
実行結果は以下の通り。

生成されたデータは無事読み込めたので、ひとまずデータの保存形式については問題なさそうです。
今回のコードを元にして、バックテスト用のデータを蓄積していきます。
まとめ
今回は、 「JSON形式のデータの中身を指定すること」の重要性を再確認できました。
コードもChatGPTに書かせっぱなしにするのではなく、自分の目でもきちんと確認していくことが欠かせません。
今後は、今回生成したデータを既存のbotに組み込んでバックテストに使えるかどうかも検証していきます。