GMOコインのローソク足(OHLC)データをPythonで期間を指定して取得する方法

# はじめに
私は仮想通貨botterになるべく今更ながら奮闘しています!
その中でまず最初のステップとしてつまずくのが価格データの取得方法だと思っていて、
この記事では、gmocoinのローソク足データを期間を指定して自動で取得する方法を紹介します。

### 実装
```python:get_kline.py
import requests
import pandas as pd
from datetime import datetime, timedelta, timezone

def get_price_range(start_day, end_day):
    endPoint = 'https://api.coin.z.com/public'
    date_range = pd.date_range(start=start_day, end=end_day, freq='D')
    all_data = []  # 全ての日のデータを格納するリスト

    for day in date_range:
        day_str = day.strftime('%Y%m%d')  # APIに必要な日付形式に変換
        path = f'/v1/klines?symbol=BTC_JPY&interval=15min&date={day_str}'
        try:
            response = requests.get(endPoint + path)
            response.raise_for_status()  # HTTPエラーの確認
            df = pd.DataFrame(response.json()["data"])
            
            # タイムスタンプを日本時間に変換してインデックスに設定
            date = []
            for i in df['openTime']:
                i = int(i)
                tsdate = int(i / 1000)
                loc = datetime.fromtimestamp(tsdate, tz=timezone.utc)
                date.append(loc)
            df.index = date
            df.index = df.index.tz_convert('Asia/Tokyo')
            df.drop('openTime', axis=1, inplace=True)

            all_data.append(df)  # データをリストに追加

        except requests.exceptions.RequestException as e:
            print(f"{day_str}の価格取得でエラー発生 : ", e)

    # 各日のデータを一つのDataFrameに結合
    if all_data:
        final_df = pd.concat(all_data)
        final_df.sort_index(inplace=True)  # 日時順にソート
        return final_df
    else:
        print("データが取得できませんでした。")
        return pd.DataFrame()  # 空のデータフレームを返す

# 使用例：2023年1月1日から2023年1月7日までのデータを取得
start_day = '2023-01-1'
end_day = '2024-1-7'
df = get_price_range(start_day, end_day)
print(df)
df.to_pickle(f'main/datastore/{start_day}.pkl')  #dfを保存
```
## 解説
上から順に解説していきます。
### GMOコインのAPIリクエスト
```python:
endPoint = 'https://api.coin.z.com/public'
    date_range = pd.date_range(start=start_day, end=end_day, freq='D')
    all_data = []  # 全ての日のデータを格納するリスト

    for day in date_range:
        day_str = day.strftime('%Y%m%d')  # APIに必要な日付形式に変換
        path = f'/v1/klines?symbol=BTC_JPY&interval=15min&date={day_str}'
        try:
            response = requests.get(endPoint + path)
            response.raise_for_status()  # HTTPエラーの確認
            df = pd.DataFrame(response.json()["data"])
```
上記ではGMOコインのapiにローソク足データのリクエストをおくっています。

pd.daterange()とは指定した開始日から終了時間までの日時の範囲を生成する便利な関数です。
```python:
print(pd.date_range(start='2024-01-01', end='2024-01-05'))
```
このように指定すると以下を返してくれます。
```python:
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
               '2024-01-05'],
              dtype='datetime64[ns]', freq='D')
```
#### 取得する足の間隔の変更
```python:
    path = f'/v1/klines?symbol=BTC_JPY&interval=15min&date={day_str}'
```
また上記のコードの"15min"のところを"1min","12hour","1month"などに変更することで取得する足の間隔を変更することができます。

詳細は以下の公式ドキュメントをご参照ください。

https://api.coin.z.com/docs


## 日付の表示変更
```python:
# タイムスタンプを日本時間に変換してインデックスに設定
date = []

for i in df['openTime']:
    i = int(i)
    tsdate = int(i / 1000)
    loc = datetime.fromtimestamp(tsdate, tz=timezone.utc)
    date.append(loc)
    
df.index = date
df.index = df.index.tz_convert('Asia/Tokyo')
df.drop('openTime', axis=1, inplace=True)

all_data.append(df)  # データをリストに追加
```
取得したデータではtimestamp型になっているためそのままでもいいですが、見やすくするために日本時間に変換します。
その後データフレームのインデックスに設定します。

## 取得したリストの結合
```python:
    # 各日のデータを一つのDataFrameに結合
    if all_data:
        final_df = pd.concat(all_data)
        final_df.sort_index(inplace=True)  # 日時順にソート
        return final_df
    else:
        print("データが取得できませんでした。")
        return pd.DataFrame()  # 空のデータフレームを返す
```
最後に各日のデータを1つに結合して完成です。

## おわりに
今回は、GMOコインのローソク足データをPythonで日付範囲を指定して取得する方法を紹介しました。

今後は、このデータを活用した仮想通貨トレードBotの作成過程についても記事にまとめていこうと思っています。実際に戦略を試しながら、精度検証や自動化の部分も公開していく予定です。

もしこの記事が役に立った、面白そうだと感じた方は、いいねしてもらえると励みになります！
一緒に仮想通貨Bot開発を楽しみましょう！