Binance APIで過去のK線(ローソク足)データを取得する方法:データの欠落を防ぐには
APIを使用してバックテスト用の過去K線データを取得する際、ページネーションと重複削除が必要です。本記事では標準的な実装パターンを紹介します。
バックテスト戦略には過去のK線(ローソク足)データが不可欠です。まず Binance公式サイト で読み取り専用のAPIキーを作成し、アプリでの確認には Binance公式アプリ を使用してください(iOSについては iOSインストールガイド を参照)。
インターフェース
GET /api/v3/klines
パラメータ: symbol, interval, startTime, endTime, limit
limit の最大値は 1,000 件です。
全履歴の一括取得
不可能です。limit が 1,000 件に制限されているため、ページネーション(分割取得)が必要になります。
ページネーションの実装パターン
import time
all_klines = []
end = int(time.time() * 1000)
start = end - 365 * 24 * 3600 * 1000 # 1年前から
while start < end:
klines = client.get_klines(
symbol='BTCUSDT',
interval='1h',
startTime=start,
limit=1000
)
if not klines:
break
all_klines.extend(klines)
# 次のバッチは、今回の最後のK線の時刻 + 1ms から開始
start = klines[-1][0] + 1
time.sleep(0.5) # レート制限(APIリミット)保護
重複の削除
取得バッチの境界にあるK線が重複することがあります。各バッチの開始時間を +1ms することで回避可能です。
または、取得後に以下のように処理します:
import pandas as pd
df = pd.DataFrame(all_klines)
df = df.drop_duplicates(subset=[0]) # タイムスタンプで重複を削除
K線のデータ形式
各K線は以下の配列形式で返されます:
[
open_time, # 開始時間(ミリ秒タイムスタンプ)
open, # 始値
high, # 高値
low, # 安値
close, # 終値
volume, # 出来高
close_time, # 終了時間(ミリ秒タイムスタンプ)
quote_volume, # クォート通貨の取引額
trades, # 取引件数
taker_buy_base,
taker_buy_quote,
ignore
]
DataFrameへの変換
df = pd.DataFrame(all_klines, columns=[
'open_time','open','high','low','close','volume',
'close_time','quote_volume','trades',
'taker_buy_base','taker_buy_quote','ignore'
])
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
df.set_index('open_time', inplace=True)
df = df.astype({'open': float, 'high': float, 'low': float, 'close': float, 'volume': float})
これにより、pandas、numpy、各種バックテストライブラリで利用可能になります。
期間とデータ量
| 期間 | 1年間のK線数 |
|---|---|
| 1分 (1m) | 525,600 |
| 5分 (5m) | 105,120 |
| 15分 (15m) | 35,040 |
| 1時間 (1h) | 8,760 |
| 4時間 (4h) | 2,190 |
| 1日 (1d) | 365 |
1回あたり1,000件ずつ取得する場合:
- 1分足1年分 = 526回のリクエスト = 約4〜5分
- 1時間足1年分 = 9回のリクエスト = 数秒
複数通貨ペアの並行取得
import concurrent.futures
symbols = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT']
def fetch(s):
return get_history(s, '1h', 365)
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as ex:
results = list(ex.map(fetch, symbols))
並行処理を行う際は、APIのウェイト(Weight)上限を超えないよう注意してください。
公開データ vs 署名付きデータ
過去のK線は公開データであるため、APIキーがなくても取得可能です:
import requests
url = 'https://api.binance.com/api/v3/klines'
params = {'symbol': 'BTCUSDT', 'interval': '1h', 'limit': 1000}
r = requests.get(url, params=params)
ただし、APIキーを使用(認証)したほうが、高いウェイト制限(Weight limit)を享受できます。
年間一括データ
Binanceは過去データのダウンロード(zip形式のCSV)を提供しており、数年分を一括で入手できます:
- data.binance.vision/
月単位、K線タイプ別に分かれています。APIで取得するよりも遥かに高速です。
継続的な更新
バックテスト後の実稼働では、最新のK線を常に更新し続ける必要があります。以下の2つの方法があります:
1. 定期的なプル(REST API)
数分ごとに直近の5本程度のK線をプルし、ローカルデータを更新します。
2. WebSocket
K線のWebSocketを購読します:
wss://stream.binance.com:9443/ws/btcusdt@kline_1h
K線が更新されるたびに即座にプッシュされます。
WebSocketはリアルタイム更新に、REST APIは過去のデータの補完に適しています。
データ品質の注意点
以下の点に注意してください:
- ネットワークの揺らぎによりバッチが欠落する可能性がある
- タイムスタンプの単位を確認する(ミリ秒であり、秒ではない)
- 未確定のK線(一番新しい足)は値が変化し続ける
バックテストを行う際は、未確定の最新K線は除外するようにしてください。
データの永続化
取得したデータは以下の形式で保存するのが一般的です:
- CSV:シンプル
- Parquet:効率的な圧縮と高速な読み込み
- SQLite:検索が容易
- DuckDB:分析が高速
- 時系列データベース:膨大なデータ量の場合
中規模なデータ量であれば Parquet がおすすめです。
デリバティブ(先物)の履歴
先物のK線インターフェースは以下の通りです:
- U本位先物:
/fapi/v1/klines - コイン本位先物:
/dapi/v1/klines
パラメータと返却形式は現物(v3)と同じです。
資金調達率の履歴
GET /fapi/v1/fundingRate?symbol=BTCUSDT&limit=1000
8時間ごとのデータです。最大1,000件 = 333日分を取得可能です。
よくある質問
Q: 過去データの取得で速度制限(Rate limit)にかかりますか? A: はい。sleepを適切に入れてください。
Q: すべての通貨ペアを取得できますか? A: 可能です。ただし、上場廃止された通貨の履歴は保存期間が限られている場合があります。
Q: 1分足のデータ量はどのくらいですか? A: 1年分で約50MB(CSV形式)です。複数通貨を貯めると非常に大きくなります。
Q: バックテストでスリッページをシミュレートできますか? A: 自分でスリッページモデルを実装する必要があります。BinanceのK線データには板の情報は含まれません。
Q: 過去データは商用利用できますか? A: 自身の戦略開発に利用するのは問題ありません。再配布についてはBinanceの利用規約を確認してください。
関連ガイド
過去のK線データはバックテストの燃料です。データの取得、重複削除、永続化をマスターすれば、クオンツ戦略の成功へ大きく一歩近づきます。