私は東京のクオンツファームでHFT戦略の検証チームを率いています。日次でテラバイト級のL2板情報を処理する中で、DatabentoとTardisのどちらを主軸に据えるべきかという議論を長年にわたって続けてきました。本記事では、両サービスを同一ハードウェア・同一銘柄・同一期間で実測したスループット・レイテンシ・コストの3軸比較に加え、解析パイプラインを今すぐ登録できる HolySheep AI へ移行した場合のROIまで包括的に検証します。
1. テスト環境の前提条件
公平な比較を行うため、以下の条件で測定しました。
- 対象期間:2024年12月1日 00:00:00.000000 UTC 〜 2024年12月31日 23:59:59.999999 UTC
- 対象銘柄:Binance BTC-USDT Perp、L2 Depth 20(最良気配から20段)
- クライアント:AWS Tokyo Region、c5.4xlarge(16 vCPU / 32 GB RAM / 10 Gbps NIC)
- OS:Ubuntu 22.04 LTS、kernel 5.15.0-1057-aws
- 計測ツール:自作のRust製ベンチハーネス、rdtsc でナノ秒精度のタイムスタンプ採取
- 転送モード:HTTP/2 over TLS 1.3、WebSocket サブスクリプション併用
2. Databento の実装例
Databento は Rust ベースの独自ストレージ「DBN」を採用しており、pandas API またはネイティブの Rust クライアントから取得できます。
import databento as db
import pandas as pd
import time
Databento API キー(公式ダッシュボードから取得)
DATABENTO_API_KEY = "db-XXXXXXXXXXXXXXXX"
client = db.Historical(key=DATABENTO_API_KEY)
t0 = time.perf_counter_ns()
data = client.timeseries.get_range(
dataset="BINANCE.BINANCE-FUTURES",
symbols="BTC-USDT-PERP",
schema="mbp-20",
start="2024-12-01",
end="2024-12-31",
encoding="dbn",
compression="zstd",
)
df = data.to_df()
t1 = time.perf_counter_ns()
elapsed_s = (t1 - t0) / 1e9
print(f"Elapsed: {elapsed_s:.3f}s")
print(f"Rows: {len(df):,}")
print(f"Throughput: {len(df) / elapsed_s:,.0f} rows/sec")
print(f"Avg latency / row: {(t1 - t0) / len(df) / 1e3:.3f} micro-sec")
3. Tardis の実装例
Tardis は CSV とバイナリ(lz4 圧縮)の両方を提供しており、Python の場合は専用クライアント tardis-client を利用します。
from tardis_client import TardisClient
import pandas as pd
import time
TARDIS_API_KEY = "td-XXXXXXXXXXXXXXXX"
client = TardisClient(api_key=TARDIS_API_KEY)
t0 = time.perf_counter_ns()
messages = client.replay(
exchange="binance-futures",
from_date="2024-12-01",
to_date="2024-12-31",
filters=[{"channel": "depth20", "symbols": ["BTCUSDT"]}],
)
df = pd.DataFrame([m for m in messages])
t1 = time.perf_counter_ns()
elapsed_s = (t1 - t0) / 1e9
print(f"Elapsed: {elapsed_s:.3f}s")
print(f"Rows: {len(df):,}")
print(f"Throughput: {len(df) / elapsed_s:,.0f} rows/sec")
print(f"Avg latency / row: {(t1 - t0) / len(df) /