ビットコインのOHLCVデータを生成する

仮想通貨のOHLCVデータを生成する方法を記事にします。

価格予測の機械学習モデルに使うデータセットに使用できます。

2022年衝撃だった本

2021年の年末にタイトル買いした本をお正月休みに読み、衝撃だった本です。
日給300万円のSS級トレーダーが明かすbotterのリアル

この本を読んで、機械学習による価格予測に興味が出ました。

OHLCVデータ生成

上記の本に書かれてある通りに生成します。
仮想通貨はいろいろありますが、ビットコイン(BTC)にします。

ヒストリカルデータのダウンロード

GMOコイン

GMO コインのヒストリカルデータ から最新の日付のデータ (20220703_BTC.csv.gz) をダウンロードします。

pandasのread_csvは *.gz の圧縮ファイルも読んでくれます。

filename = '20220703_BTC.csv.gz'
file_path = os.path.join(os.getcwd(), filename)
df = pd.read_csv(file_path)
print(df)
print(df.dtypes)

以下のようなデータとなっています。

  symbol side size price timestamp
0 BTC BUY 0.0001 2603250.0 2022-07-02 21:02:00.741
1 BTC BUY 0.0001 2603851.0 2022-07-02 21:03:35.236
2 BTC SELL 0.0100 2603999.0 2022-07-02 21:05:17.352
3 BTC SELL 0.0021 2603249.0 2022-07-02 21:05:18.863
4 BTC SELL 0.0010 2603249.0 2022-07-02 21:05:18.863
... ... ... ... ... ...
4390 BTC BUY 0.0100 2627750.0 2022-07-03 20:56:13.672
4391 BTC BUY 0.0001 2628221.0 2022-07-03 20:56:53.891
4392 BTC SELL 0.0100 2628499.0 2022-07-03 20:57:39.251
4393 BTC SELL 0.0900 2628499.0 2022-07-03 20:57:39.251
4394 BTC BUY 0.0001 2628639.0 2022-07-03 20:59:49.464

symbol object
side object
size float64
price float64
timestamp object
dtype: object

ヒストリカルデータの整形

timestampのカラムがobject型になっているので、timestamp型に変換します。
取引時刻のタイムゾーンは UTC みたいです。

df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
print(df)
print(df.dtypes)
  symbol side size price timestamp
0 BTC BUY 0.0001 2603250.0 2022-07-02 21:02:00.741000+00:00
1 BTC BUY 0.0001 2603851.0 2022-07-02 21:03:35.236000+00:00
2 BTC SELL 0.0100 2603999.0 2022-07-02 21:05:17.352000+00:00
3 BTC SELL 0.0021 2603249.0 2022-07-02 21:05:18.863000+00:00
4 BTC SELL 0.0010 2603249.0 2022-07-02 21:05:18.863000+00:00
... ... ... ... ... ...
4390 BTC BUY 0.0100 2627750.0 2022-07-03 20:56:13.672000+00:00
4391 BTC BUY 0.0001 2628221.0 2022-07-03 20:56:53.891000+00:00
4392 BTC SELL 0.0100 2628499.0 2022-07-03 20:57:39.251000+00:00
4393 BTC SELL 0.0900 2628499.0 2022-07-03 20:57:39.251000+00:00
4394 BTC BUY 0.0001 2628639.0 2022-07-03 20:59:49.464000+00:00

symbol object
side object
size float64
price float64
timestamp datetime64[ns, UTC]
dtype: object

timestampをローソク足の分足の単位に丸めます。今回は30分足とします。
pandas.Series.dt.floor を使います。
1800S = 60 sec * 30 (分足) です。

df['timestamp'] = df['timestamp'].dt.floor('1800S')
print(df)
  symbol side size price timestamp
0 BTC BUY 0.0001 2603250.0 2022-07-02 21:00:00+00:00
1 BTC BUY 0.0001 2603851.0 2022-07-02 21:00:00+00:00
2 BTC SELL 0.0100 2603999.0 2022-07-02 21:00:00+00:00
3 BTC SELL 0.0021 2603249.0 2022-07-02 21:00:00+00:00
4 BTC SELL 0.0010 2603249.0 2022-07-02 21:00:00+00:00
... ... ... ... ... ...
4390 BTC BUY 0.0100 2627750.0 2022-07-03 20:30:00+00:00
4391 BTC BUY 0.0001 2628221.0 2022-07-03 20:30:00+00:00
4392 BTC SELL 0.0100 2628499.0 2022-07-03 20:30:00+00:00
4393 BTC SELL 0.0900 2628499.0 2022-07-03 20:30:00+00:00
4394 BTC BUY 0.0001 2628639.0 2022-07-03 20:30:00+00:00

pandas.DataFrame.groupby を使って、OHLCVデータに変換します。

df = pd.concat([
    df.groupby('timestamp')['price'].nth(0).rename('open'),
    df.groupby('timestamp')['price'].max().rename('high'),
    df.groupby('timestamp')['price'].min().rename('low'),
    df.groupby('timestamp')['price'].nth(-1).rename('close'),
    df.groupby('timestamp')['size'].sum().rename('volume'),
], axis=1)
print(df)
                          open high low close volume
timestamp
2022-07-02 21:00:00+00:00 2603250.0 2611250.0 2602240.0 2610115.0 0.4910
2022-07-02 21:30:00+00:00 2610001.0 2618350.0 2607200.0 2615750.0 0.9302
2022-07-02 22:00:00+00:00 2616000.0 2616000.0 2612918.0 2615268.0 0.9668
2022-07-02 22:30:00+00:00 2615484.0 2616217.0 2612617.0 2613750.0 1.0492
2022-07-02 23:00:00+00:00 2613836.0 2614239.0 2600058.0 2601250.0 0.7396
... ... ... ... ... ...
2022-07-03 18:30:00+00:00 2597250.0 2599833.0 2595683.0 2599250.0 0.3323
2022-07-03 19:00:00+00:00 2599628.0 2604999.0 2598950.0 2604999.0 0.9040
2022-07-03 19:30:00+00:00 2605250.0 2637500.0 2605250.0 2635250.0 3.2975
2022-07-03 20:00:00+00:00 2636000.0 2653935.0 2631000.0 2640592.0 3.2585
2022-07-03 20:30:00+00:00 2639040.0 2639040.0 2624500.0 2628639.0 0.7154

ビットコインの30分足のOHLCV データの完成です。

OHLCVデータの保存と読み込み

csvで保存する方法と読み込む方法です。

# csvで保存する。
filename = 'BTC_30min.csv'
file_path = os.path.join(os.getcwd(), filename)
df.to_csv(file_path)

# csvを読み込む。0列をIndexとして読み込む。
df = pd.read_csv(file_path, index_col=0)
print(df)
print(df.dtypes)
print(df.index.dtype)

# Indexの"timestamp"がobject型になっているので、datetime型に変換する。
df.index = pd.to_datetime(df.index, utc=True)
print(df)
print(df.dtypes)
print(df.index.dtype)

pickleで保存する方法と読み込む方法です。

# pickleで保存する。
filename = 'BTC_30min.pkl'
file_path = os.path.join(os.getcwd(), filename)
df.to_pickle(file_path)

# pickleを読み込む。
df = pd.read_pickle(file_path)
print(df)
print(df.dtypes)
print(df.index.dtype)