Bot

仮想通貨botの開発を本格的に始めてみる#23(2023/10/25)「ローソク足データを取得する」

2023年10月25日

前回の内容に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

今回のテーマは「過去の価格データを蓄積する」こと。

参考にしたのはこちらの記事です。

下準備

#20の記事で直面していた「価格データの読み込み」問題は解決しました。

メイン処理を二つ並行して行なっていたことが原因だったようです。

ファイルから読み込む処理だけを稼働させる状態にしてコードを実行したところ、過去データからの取得を元にしてコンソールに情報を表示させることができました。

なぜ、過去のデータの蓄積が必要なのか

botを最低限のレベルで稼働させるだけであれば、過去価格データは必要ありません。

しかし、前回の記事でまとめたように「バックテスト」を行う際は、過去のデータが多ければ多いほどテストの結果がより正確なものになる可能性があるのです。

また、価格データをCryptowatchから取得する以上、APIの使用回数制限に引っかかってしまうことは避けられません。

そこで、「APIの使用を最低限に抑えながらバックテスト用の価格データを蓄積する」必要が出てきたのです。

今回の目標を詳しく言うと「1分足・5分足・1時間足の価格データを自動で取得して更新し続けるプログラムを実装すること」です。

データの取得と追加

10月からCryptowatchのAPIが使えなくなってしまったため、取引所のAPIデータを直接利用してローソク足データを取得するコードをChatGPTに書かせることにしました。

コードは以下の通り。

import requests
import json
from datetime import datetime, timedelta  # timedeltaを追加
import time

# APIエンドポイントのURL
api_url = "https://api.bitflyer.com/v1/getexecutions?product_code=FX_BTC_JPY&count=500"

# ローソク足データを生成する関数
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"]
            }
            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"]
    
    # 最後の足を追加
    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)
        # ローソク足データを生成(例: 5分足)
        five_minute_candlestick_data = generate_candlestick_data(executions, timeframe_minutes=5)
        # ローソク足データを生成(例: 15分足)
        fifteen_minute_candlestick_data = generate_candlestick_data(executions, timeframe_minutes=15)
        # ローソク足データを生成(例: 1時間足)
        hour_candlestick_data = generate_candlestick_data(executions, timeframe_minutes=60)
        
        # データをJSONファイルに保存(追記モード)
        with open('minute_candlestick_data.json', 'a') as json_file:
            json.dump(minute_candlestick_data, json_file)
            json_file.write('\n')
        
        with open('five_minute_candlestick_data.json', 'a') as json_file:
            json.dump(five_minute_candlestick_data, json_file)
            json_file.write('\n')
        
        with open('fifteen_minute_candlestick_data.json', 'a') as json_file:
            json.dump(fifteen_minute_candlestick_data, json_file)
            json_file.write('\n')
        
        with open('hour_candlestick_data.json', 'a') as json_file:
            json.dump(hour_candlestick_data, json_file)
            json_file.write('\n')
        
        print("Candlestick data saved.")
    else:
        print("Failed to fetch data or generate candlestick data.")
    
    # 10秒待機
    time.sleep(10)

上記のコードでは、1分足・5分足・15分足・1時間足のデータを並行して作成できるようにしています。

データ取得の間隔は10秒ごとですが、()内の数字を変えることで変更することもできます。

まとめ

ChatGPTをフル活用して「ローソク足データの蓄積をするためのコード」を書くことができました。

今の所問題なく稼働しているため、今後はレンタルサーバーで24時間稼働させ続ける予定です。

価格取得ができたため、ようやくバックテスト用のコードの学習を再開できそうです。

今後も一つずつ学習を進めていきます。

-Bot