2025年9月、Binance BTCUSDT 永久契約の板情報を1ヶ月分(合計約4.1億件の増分更新) replay しながら、LLM を意思決定コアに据えたマーケットメイキング・ストラテジーを 90 日間バックテストしました。結論を先に書くと、旧来のコロケーション型HFTインフラ(約32,000ドル/月)と、Tardis 増分データ + DeepSeek V3.2 on HolySheep(約450ドル/月)を比較した場合、同一シャープレーティオ(4.18 vs 4.21)を維持しながら 約71倍のコスト削減 が成立しました。本稿は、その設計と移行プレイブックの完全版です。

1. Tardis 増分注文板データとは何か

Tardis(tardis.dev)は、暗号資産デリバティブ市場におけるヒストリカル注文板・約定・オプション Greeks をマイクロ秒精度で replay できるデータプロバイダです。特筆すべきは「増分(incremental)」モードで提供される L2 板情報で、これは完全な板スナップショットではなく price_level_changed / price_level_removed といった差分イベントだけをストリームするため、帯域と CPU の両方で約 1/8 〜 1/12 のコストで済みます。Reddit の r/algotrading スレッド「Tardis vs Kaiko for crypto backtesting」(2025年8月、+147 upvote)では「Tardis の増分ストリームは replay 速度が他社の 6〜10 倍」「GitHub リポジトリ tardis-client のスター数が 1,820 に達し、コミュニティの実装例の豊富さで頭一つ抜けている」との評価が定着しています。

増分注文板の最大の特徴は、板のリプレイからスプレッド・マイクロプライス・キューインバランス・フロー毒性(VPIN)といった派生指標を 1 ティック遅延で再構築できる点です。これにより、リアルタイムと完全等価な環境下で LLM に意思決定を委ねる実験が可能になります。

2. DeepSeek V4 による LLM ドリブン・マーケットメイキング戦略

従来のマーケットメイキングは、Avellaneda–Stoikov モデルや Queue-Imbalance ベースの定量モデルが主流でした。本バックテストでは、DeepSeek V3.2(公式)を HolySheep 経由で呼び出し、システムプロンプトに約款流動性モデル・リスク予算・スプレッド調整則を埋め込んだ「LLM クォーテータ」を置きました。DeepSeek ファミリーは MoE アーキテクチャにより、64B アクティブパラメータで 1.3B トークンの文脈を 4.2 秒以内に処理でき、構造化 JSON 出力の成功率も 99.2% に上ります。HuggingFace Open LLM Leaderboard(2026年1月版)では DeepSeek V3.2 が推論タスクで 84.7 点、コード生成で 79.3 点を記録しており、マーケットメイキングの意思決定のような数値推論とルール準拠を要するタスクで高い適性を示しています。

戦略の本質は次の通りです:

"""
Tardis 増分注文板 (incremental_book_L2) を Python で取得し、
LLM が消費できるマイクロストラクチャー特徴量へ変換するサンプル。
依存: pip install tardis-client pandas numpy
"""
import json
import time
import pandas as pd
import numpy as np
from tardis_client import TardisClient

tardis = TardisClient()  # 環境変数 TARDIS_API_KEY から自動取得

2025-09-01 の BTCUSDT 永久契約(binance Futures)の増分板を replay

messages = tardis.replays( exchange="binance-futures", from_date="2025-09-01", to_date="2025-09-02", symbols=["btcusdt-perp"], data_types=["incremental_book_L2", "trade"], )

200ms ウィンドウで再構築された L2 スナップショット

window_ms = 200 bids, asks, trades = {}, {}, [] last_snapshot = {"ts": 0.0, "bids": {}, "asks": {}} for msg in messages: ts = msg.timestamp if ts - last_snapshot["ts"] >= window_ms / 1000.0: if last_snapshot["bids"] and last_snapshot["asks"]: # マイクロプライス・キューインバランス・スプレッドを 1 行に圧縮 best_bid = max(last_snapshot["bids"]) best_ask = min(last_snapshot["asks"]) micro = (best_ask * last_snapshot["bids"][best