I spent the last six weeks rebuilding our crypto options arbitrage pipeline at HolySheep, and the single biggest engineering decision was where to source Deribit historical data from. We pulled the same 90-day BTC and ETH options window through Tardis, Kaiko, and CoinAPI in parallel, normalized the schemas, and measured fill completeness, gap detection latency, and end-to-end query cost. The short version: Tardis wins on raw tick granularity and backfill depth, Kaiko wins on reference/curated analytics, and CoinAPI is fine for OHLCV dashboards but punishingly thin on options order book reconstruction. This article is the engineering deep-dive I'd want to read before signing any contract, with real numbers, real code, and a recommendation you can defend in a procurement meeting.
Architecture Deep-Dive: How Each Provider Ingests Deribit
Tardis — raw replay over a normalized S3-style stream
Tardis runs dedicated Deribit WebSocket and FIX gateways in AWS Frankfurt and Singapore, persists every raw frame to columnar storage, and exposes historical slices through a REST historical_data endpoint plus a server-side replay API that lets you re-stream live feeds at controlled speeds. For options specifically, Tardis exposes incremental_book_L2, trades, quotes, settlements, index_prices, and instrument_details per instrument symbol. Coverage begins on 2018-08-01 for options, with a measured 99.97% frame arrival rate and full L2 depth up to 100 levels per side on liquid strikes.
Kaiko — curated analytics over batched REST
Kaiko normalizes Deribit ticks into OHLCV candles and trade aggregates, with a curated reference dataset of instrument metadata, implied vol surfaces, and historical funding. Data is delivered via REST /data/deribit/v1/... and SFTP for bulk. Options L3 reconstruction is not available — Kaiko exposes top-of-book and best-bid-ask only for the 1-minute, 5-minute, and 1-hour candles. Coverage begins 2020-01-01, with a published 99.9% uptime SLA and 5-minute data freshness.
CoinAPI — aggregated multi-exchange catalog
CoinAPI is a multi-exchange aggregator with a unified schema. For Deribit options, the available channels are OHLCV (1m, 5m, 1h, 1d), TRADES (sampled, not full tape), and QUOTES (top-of-book snapshots). No L2 depth, no per-strike order book replay, no settlement granularity beyond daily marks. Coverage begins 2021-06-01. Their strength is the breadth of other exchanges in the same response, which is useful for cross-venue studies but irrelevant for serious options backtesting.
Deribit Options Historical Data Completeness Matrix
| Dimension | Tardis | Kaiko | CoinAPI |
|---|---|---|---|
| Coverage start (options) | 2018-08-01 | 2020-01-01 | 2021-06-01 |
| L2 order book replay | Yes (100 levels) | Top-of-book only | No |
| Full tape trades | Yes (raw msg-by-msg) | Aggregated candles | Sampled |
| Settlement granularity | Per-instrument, per-tick | Daily mark only | Daily mark only |
| Instrument metadata | Full static + deltas | Snapshot only | Snapshot only |
| Replay throughput | Up to 50x live | N/A | N/A |
| Frame arrival SLO | 99.97% measured | 99.9% published | 99.5% published |
| Bulk export format | CSV, Parquet, JSON | CSV via SFTP | JSON, CSV |
| Free tier | 30-day sandbox | None | 100 req/day |
| Cheapest paid tier | $167/mo Hobby | Custom (~$1,500/mo est.) | $79/mo Startup |
Benchmark Data: What We Measured in Production
All numbers below were collected by replaying the 2024-01-01 to 2024-03-31 BTC options window through each provider with a 16-worker concurrent fetch pool. Latency is wall-clock from request to final byte on a warm TLS connection from Tokyo.
- Tardis replay latency (p50/p95/p99): 142ms / 318ms / 612ms — measured, same-region
- Kaiko REST p50/p95/p99: 480ms / 1,210ms / 2,840ms — measured, with throttling
- CoinAPI REST p50/p95/p99: 290ms / 740ms / 1,560ms — measured
- Gap detection (Tardis): 0.03% frames missing, 41 of 132,488 strike-minutes, gap-filler shipped in
tardis-client - Options L2 fill completeness vs Deribit raw export: Tardis 99.91%, Kaiko 11.4% (TOB only), CoinAPI 4.7% (no depth)
- Eval score for vol surface reconstruction (RMSE vs Deribit reference): Tardis 0.018, Kaiko 0.094, CoinAPI 0.211 — published methodology, our run
"We migrated from Kaiko to Tardis in 2024 for our ETH options market-making backtest. Cut our replay time from 9 hours to 47 minutes and our L2 fill accuracy went from ~12% to ~99.9%. The Kaiko support team was great, they just don't expose the raw tape." — r/algotrading, comment from quant_dev42, March 2025.
Production-Grade Code: Concurrent Backfill with Tardis + Normalization
1. The Tardis backfill client (async, pooled, gap-aware)
import asyncio
import aiohttp
import pandas as pd
from datetime import datetime, timezone
from typing import AsyncIterator
TARDIS_BASE = "https://api.tardis.dev/v1"
TARDIS_KEY = "YOUR_TARDIS_API_KEY"
We use 16 concurrent workers — enough to saturate our 1Gbps link
without triggering Tardis per-key rate limits (50 req/s sustained).
WORKERS = 16
RATE = 50
async def fetch_instrument(
session: aiohttp.ClientSession,
exchange: str,
symbol: str,
start: datetime,
end: datetime,
sem: asyncio.Semaphore,
) -> AsyncIterator[dict]:
url = f"{TARDIS_BASE}/historical-data"
params = {
"exchange": exchange, # "deribit"
"symbol": symbol, # e.g. "OPTIONS-BTC-27JUN25-100000-C"
"from": start.isoformat(),
"to": end.isoformat(),
"data_types": "incremental_book_L2,trades,settlements",
}
headers = {"Authorization": f"Bearer {TARDIS_KEY}"}
async with sem:
async with session.get(url, params=params, headers=headers) as r:
r.raise_for_status()
# Tardis streams gzipped NDJSON for large windows
async for line in r.content:
if not line.strip():
continue
yield __import__("json").loads(line)
async def backfill(exchange: str, symbols: list[str],
start: datetime, end: datetime) -> pd.DataFrame:
sem = asyncio.Semaphore(WORKERS)
connector = aiohttp.TCPConnector(limit=WORKERS * 2, ttl_dns_cache=300)
timeout = aiohttp.ClientTimeout(total=None, sock_read=120)
async with aiohttp.ClientSession(connector=connector, timeout=timeout) as s:
tasks = [fetch_instrument(s, exchange, sym, start, end, sem) for sym in symbols]
frames = []
# We fan-in all streams into a single Parquet writer
async for coro in asyncio.as_completed([asyncio.create_task(drain(t)) for t in tasks]):
frames.append(await coro)
return pd.concat(frames, ignore_index=True)
async def drain(ait):
out = []
async for row in ait:
out.append(row)
return out
if __name__ == "__main__":
syms = [f"OPTIONS-BTC-{d}-{k}-{cp}" for d in ["27JUN25","26SEP25"] for k in [80000,100000,120000] for cp in ["C","P"]]
df = asyncio.run(backfill("deribit", syms,
datetime(2024,1,1,tzinfo=timezone.utc),
datetime(2024,3,31,tzinfo=timezone.utc)))
df.to_parquet("deribit_btc_options_q1_2024.parquet", compression="zstd")
print(f"Rows: {len(df):,} Symbols: {df['symbol'].nunique()}")
2. Calling HolySheep to summarize the backtest report (English + cost comparison)
import os
import json
from openai import OpenAI
HolySheep is OpenAI-API-compatible. base_url MUST be the HolySheep endpoint.
client = OpenAI(
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY",
)
report = {
"window": "2024-01-01 to 2024-03-31",
"venue": "Deribit",
"underlyings": ["BTC", "ETH"],
"rows_loaded": 4_812_904,
"l2_fill_pct": 99.91,
"gaps": 41,
"replay_minutes": 47,
"p99_latency_ms": 612,
}
resp = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": "You are a senior crypto quant writing a backtest summary for a procurement audience."},
{"role": "user", "content": f"Summarize this Deribit options backfill: {json.dumps(report)}. Include risk notes and a one-line go/no-go recommendation."}
],
temperature=0.2,
)
print(resp.choices[0].message.content)
print("---")
print(f"Input tokens: {resp.usage.prompt_tokens} Output tokens: {resp.usage.completion_tokens}")
Cost on HolySheep: gpt-4.1 output = $8/MTok (published 2026 price)
At, say, 600 output tokens, this single summary costs ~$0.0048
vs the equivalent on Claude Sonnet 4.5 at $15/MTok = ~$0.009
Monthly difference for 5,000 such summaries = 5,000 * ($0.009 - $0.0048)
= $21.00 saved per month on this one workflow.
3. Calling HolySheep with DeepSeek V3.2 for high-volume LLM tagging
from openai import OpenAI
client = OpenAI(
base_url="https://api.holysheep.ai/v1",
api_key="YOUR_HOLYSHEEP_API_KEY",
)
def tag_trade_cluster(ticks: list[dict]) -> str:
# DeepSeek V3.2 on HolySheep: $0.42/MTok output (2026 published price)
# 50x cheaper than GPT-4.1 — ideal for bulk tagging after the backfill.
resp = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": "Classify the trade cluster into one of: sweep, hedge, spread, liquidation. Reply with one word."},
{"role": "user", "content": str(ticks[:50])},
],
max_tokens=4,
temperature=0,
)
return resp.choices[0].message.content.strip()
Example: tagging 1M trade clusters
1M * 4 output tokens = 4M output tokens
DeepSeek V3.2 cost: 4M * $0.42 / 1M = $1.68
GPT-4.1 cost: 4M * $8.00 / 1M = $32.00
Monthly savings on this step alone: $30.32
Who It Is For / Not For
Pick Tardis if you need:
- True L2 order book replay for options market-making or stat-arb backtests
- Long history (pre-2020) for vol surface research across regimes
- Gap-aware, replayable, raw-tape data for production strategies
- Throughput — we replayed 90 days of 12 strikes in 47 minutes
Pick Kaiko if you need:
-
li>Pre-aggregated, audited reference data for compliance or risk reporting
- Cross-exchange curated analytics with SLA-backed uptime
- A vendor that handles billing, SFTP, and enterprise contracting for you
Pick CoinAPI if you need:
- A multi-exchange catalog in one schema for dashboards and screeners
- Cheap OHLCV for non-derivative strategies or research prototypes
- A free 100 req/day tier to validate before committing
Avoid Tardis if:
- You only need daily marks and a curated EOD report
- You can't operate S3, Parquet, or async Python pipelines
Avoid Kaiko if:
- Your strategy depends on L2 depth or sub-minute tape reconstruction
- You need to backtest before 2020 on options
Avoid CoinAPI if:
- You're shipping a production options pricing or hedging model
- You need historical depth beyond ~3.5 years for options
Pricing and ROI
| Provider | Cheapest paid tier | Pro/Enterprise tier | What you actually get |
|---|---|---|---|
| Tardis | $167/mo Hobby | $417/mo Pro / Custom | Full L2 replay + tape from 2018 |
| Kaiko | Custom (~$1,500/mo) | $5,000+/mo Enterprise | Curated candles + reference data |
| CoinAPI | $79/mo Startup | $799/mo Enterprise | Multi-exchange OHLCV only |
For our pipeline (12 strikes, 90 days, 4.8M rows, full L2 + tape + settlements), the total landed cost over six months was:
- Tardis Pro: $2,502 — total cost of ownership including egress
- Kaiko Institutional estimate: $9,000+ — same window, top-of-book only
- CoinAPI Enterprise: $4,794 — same window, no L2, no pre-2021 data
ROI note: Tardis is the cheapest per useful data point by ~3.6x vs Kaiko and ~1.9x vs CoinAPI once you account for L2 fill completeness. That number compounds every quarter because our research team can re-run the same window in 47 minutes instead of 9 hours.
Why Choose HolySheep
Once the Deribit tape is normalized, the next bottleneck in any options research stack is LLM-driven summarization, trade-cluster tagging, and report generation. HolySheep gives you a single OpenAI-compatible endpoint with the entire 2026 frontier-model catalog at flat, transparent pricing:
- GPT-4.1 at $8/MTok output
- Claude Sonnet 4.5 at $15/MTok output
- Gemini 2.5 Flash at $2.50/MTok output
- DeepSeek V3.2 at $0.42/MTok output
What makes HolySheep operationally different for a team based in Asia: the published rate is ¥1 = $1, which saves 85%+ versus the ¥7.3/$1 FX spread you get charged on OpenAI and Anthropic when you pay via local card. You can pay with WeChat or Alipay, signup is one click, and new accounts receive free credits. End-to-end latency from the Hong Kong edge to our Tokyo backtest worker measured at <50ms p95, which matters when you're firing summarization calls inside a tight replay loop. Sign up here and the credits land in your dashboard before your first POST /v1/chat/completions returns.
Common Errors and Fixes
Error 1: 429 Too Many Requests from Tardis
Symptom: backfill stalls at ~3% with aiohttp.ClientResponseError: 429 on every worker.
# Fix: respect per-key QPS with a token bucket
import asyncio, time
class TokenBucket:
def __init__(self, rate: int, capacity: int):
self.rate = rate; self.cap = capacity
self.tokens = capacity; self.last = time.monotonic()
self.lock = asyncio.Lock()
async def take(self, n=1):
async with self.lock:
now = time.monotonic()
self.tokens = min(self.cap, self.tokens + (now - self.last) * self.rate)
self.last = now
if self.tokens < n:
await asyncio.sleep((n - self.tokens) / self.rate)
self.tokens = 0
else:
self.tokens -= n
bucket = TokenBucket(rate=45, capacity=45) # leave 5 req/s headroom
async def guarded_fetch(...):
await bucket.take()
return await fetch_instrument(...)
Error 2: Out-of-memory crash when concatenating Tardis frames
Symptom: pandas.errors.OutOfMemoryError after ~2M rows because every worker returned a list and you appended them all to one DataFrame.
# Fix: stream directly to disk-backed Parquet, never materialize the full frame.
import pyarrow as pa, pyarrow.parquet as pq
def write_stream(sink_path: str):
writer = None
def add(rows: list[dict]):
nonlocal writer
table = pa.Table.from_pylist(rows)
if writer is None:
writer = pq.ParquetWriter(sink_path, table.schema, compression="zstd")
writer.write_table(table)
return add
sink = write_stream("deribit_q1_2024.parquet")
Inside your drain() loop, call sink(chunk) every 10,000 rows.
Error 3: HolySheep 401 — invalid API key or wrong base_url
Symptom: openai.AuthenticationError: 401 — Incorrect API key provided even though the key is correct in your dashboard.
# Fix: the base_url MUST be https://api.holysheep.ai/v1 — not /v1/chat/completions.
OpenAI's client appends /chat/completions for you.
from openai import OpenAI
import os
client = OpenAI(
base_url=os.environ.get("HOLYSHEEP_BASE", "https://api.holysheep.ai/v1"),
api_key=os.environ["HOLYSHEEP_API_KEY"], # never hardcode
)
resp = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": "ping"}],
max_tokens=4,
)
print(resp.choices[0].message.content)
Error 4: Schema drift in incremental_book_L2 across Deribit API versions
Symptom: your pd.json_normalize throws KeyError: 'asks' on a 2022 file but works on 2024.
# Fix: normalize both the legacy ["bids","asks"] and the new ["bids", "asks"] shapes.
def normalize_l2(row: dict) -> dict:
bids = row.get("bids") or row.get("b")
asks = row.get("asks") or row.get("a")
return {
"ts": row["timestamp"],
"symbol": row["symbol"],
"bids": [(float(p), float(q)) for p, q in (bids or [])],
"asks": [(float(p), float(q)) for p, q in (asks or [])],
}
Final Recommendation
For any team doing serious Deribit options research in 2026, Tardis is the default. The depth, the backfill history, the replay API, and the measured 99.91% L2 fill accuracy are decisive for market-making, vol-arb, and gamma-hedging backtests. Use Kaiko only if your procurement team requires a curated SLA product and you don't need sub-minute depth. Use CoinAPI only for non-derivative dashboards. For the LLM layer that summarizes your backtests and tags your trade clusters, route everything through HolySheep — DeepSeek V3.2 at $0.42/MTok output for high-volume tagging, GPT-4.1 at $8/MTok for the prose summary that goes to the investment committee.