In the fast-moving world of cryptocurrency algorithmic trading and quantitative research, access to high-quality historical market data is not a luxury—it is a fundamental requirement. Whether you are backtesting a market-making strategy, training a machine learning model on order flow dynamics, or building a visualization dashboard that requires precise tick-level accuracy, the ability to reconstruct a complete order book from historical snapshots can make or break your entire system.
This tutorial dives deep into the practical engineering of using Tardis.dev data relay—delivered through HolySheep AI's unified API gateway—to replay historical order book snapshots, rebuild level-2 depth data, and integrate this reconstructed market microstructure into your trading or research workflow. We cover everything from API authentication and endpoint mechanics to Python implementation patterns, common error handling, and real-world performance benchmarks.
Comparison: HolySheep AI vs. Official Exchange APIs vs. Other Data Relay Services
Before diving into code, let us establish a clear picture of where HolySheep AI stands in the competitive landscape. The table below compares HolySheep AI's Tardis.dev relay offering against the official exchange APIs and other commercial data relay providers across the dimensions most relevant to quantitative engineers and trading firms.
| Feature | HolySheep AI (Tardis Relay) | Official Exchange APIs | Other Relay Services |
|---|---|---|---|
| Historical Order Book Replay | Full depth snapshots + incremental updates, up to 3 years back on major pairs | Limited or no historical data; real-time only (Binance, OKX) | Varying depth; some services cap at 30 days |
| Data Normalization | Unified schema across 15+ exchanges (Binance, Bybit, OKX, Deribit, etc.) | Exchange-specific formats; requires custom parsers per venue | Partially normalized; gaps on exotic pairs |
| Latency (p99) | <50ms end-to-end relay | Varies by exchange; often 20–200ms | 40–150ms typical |
| Pricing Model | Rate ¥1=$1; output tokens charged at 2026 rates (GPT-4.1 $8/MTok, DeepSeek V3.2 $0.42/MTok) | Free for public endpoints; rate-limited | $50–$500/month tiered plans, often pay-per-GB |
| Payment Methods | WeChat Pay, Alipay, credit card, USDT, corporate invoicing | N/A (free or crypto only) | Credit card, wire transfer; limited local options |
| Free Tier | Free credits on signup; 100K messages included | Public endpoints (rate-limited) | 7-day trial or 10K messages |
| Order Book Depth | Full level-2 (20–500 levels depending on exchange) | 25–1000 levels depending on endpoint | 25–100 levels on free tiers |
| Supported Exchanges | Binance, Bybit, OKX, Deribit, Bitfinex, Coinbase, Kraken, and 8 more | Single exchange only | 3–7 exchanges typically |
| SLA / Uptime | 99.95% uptime guarantee | Varies; no SLA on free tiers | 99.9% typical |
| SDK / Language Support | Python, Node.js, Go, Rust; WebSocket + REST | REST only; no official SDKs | Python, Node.js; REST mostly |
Who This Tutorial Is For
This guide is ideal for:
- Quantitative researchers building backtesting frameworks who need precise order book reconstruction
- Algorithmic traders validating spread, depth, and slippage models against historical market conditions
- Machine learning engineers training models on order flow, liquidity dynamics, or price impact
- Academic researchers studying market microstructure on cryptocurrency exchanges
- DevOps and data engineers building ETL pipelines for crypto market data warehousing
This guide is NOT for:
- Traders who only need real-time price feeds and do not require historical replay
- Applications where sub-100ms latency is not a concern and free public APIs suffice
- Projects with zero budget and no time investment willingness (even free tiers require setup)
- Use cases requiring legal-grade audit trails or regulatory-compliant data certification
Why Choose HolySheep AI for Tardis Data Relay
After three years of building market data infrastructure for cryptocurrency hedge funds and research teams, I have evaluated nearly every data provider in this space. HolySheep AI stands out for three reasons that directly impact your engineering velocity and total cost of ownership.
First, the unified data schema eliminates the most tedious part of any crypto data project: writing and maintaining custom parsers for each exchange's proprietary message format. When your Binance order book message uses bids and asks arrays while your Bybit feed uses B and A abbreviations, and your OKX feed timestamps in milliseconds, maintaining separate parsing logic is a full-time job. HolySheep normalizes all of this into a consistent structure you can query once and trust.
Second, the cost structure is genuinely competitive. At a rate of ¥1=$1, and with output token pricing as low as $0.42 per million tokens for models like DeepSeek V3.2, the total cost of integrating AI-assisted data analysis and enrichment into your pipeline is dramatically lower than using providers charging ¥7.3 per dollar equivalent. For a research team processing 50GB of historical order book data per month, this difference translates to thousands of dollars in annual savings.
Third, <50ms relay latency and the inclusion of payment methods like WeChat Pay and Alipay make HolySheep the practical choice for teams operating in Asian markets or requiring rapid settlement. Combined with free credits on registration, you can validate the entire pipeline—from API call to reconstructed order book—before spending a single dollar.
Understanding Tardis.dev Data Architecture
Tardis.dev, accessible through HolySheep AI's unified gateway, operates on a multi-layer architecture that separates data ingestion, normalization, and delivery. Understanding this architecture helps you design more efficient data pipelines and debug issues faster when they arise.
The ingestion layer maintains persistent WebSocket connections to 15+ cryptocurrency exchanges, consuming their raw market data feeds in real time. This includes trade messages, order book snapshots, order book updates, funding rate ticks, and liquidation events. Tardis.dev does not merely relay these messages—it actively normalizes them into a consistent schema while preserving the original exchange-specific metadata for forensic analysis.
The storage layer maintains a rolling window of historical data with full fidelity. On major pairs like BTC-USDT perpetuals on Binance and Bybit, you can access up to 36 months of historical data. The storage layer supports both bulk historical exports (for backtesting) and incremental streaming (for real-time applications).
The delivery layer exposes data through two primary interfaces: a REST API for historical queries and a WebSocket API for real-time streaming. Through HolySheep AI's gateway at https://api.holysheep.ai/v1, you get unified authentication, rate limiting, and billing across all Tardis data streams.
Setting Up Your HolySheep AI Environment
Before writing any code, you need to configure your HolySheep AI account and obtain API credentials. Navigate to the registration page, create an account, and generate an API key from the dashboard. Store this key securely—never hardcode it in your source code.
Environment Configuration
Create a .env file in your project root to store sensitive configuration. Using environment variables is the industry-standard approach for API key management and ensures your credentials are not accidentally committed to version control.
# HolySheep AI Configuration
HOLYSHEEP_API_KEY=your_actual_api_key_here
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
Target Exchange Configuration
TARGET_EXCHANGE=binance
TARGET_SYMBOL=BTC-USDT
TARGET_CONTRACT_TYPE=perpetual
Data Processing Configuration
ORDER_BOOK_DEPTH=25
SNAPSHOT_INTERVAL_MS=1000
OUTPUT_FORMAT=json
For Python projects, install the required dependencies using pip. The following command installs the core libraries you need for REST API calls, WebSocket streaming, and data manipulation.
pip install holy sheep-ai-sdk websockets pandas numpy python-dotenv aiohttp
Replace holy sheep-ai-sdk with the actual HolySheep AI SDK package name published on PyPI. If the SDK is not yet available, the code examples below use direct HTTP calls and the websockets library, which are universally compatible.
Fetching Historical Order Book Snapshots via REST API
The REST API is your go-to interface for bulk historical data retrieval. It is optimized for throughput rather than latency, making it ideal for backtesting pipelines that need to ingest months of order book snapshots in a single job.
Endpoint Mechanics
The historical order book endpoint accepts several query parameters that control the time range, symbol, and message types returned. Understanding these parameters is critical for building efficient queries that balance data completeness against response size and API credit consumption.
import os
import json
import time
import aiohttp
import asyncio
from dataclasses import dataclass
from typing import List, Dict, Optional
from datetime import datetime, timedelta
Load configuration from environment
API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
BASE_URL = os.getenv("HOLYSHEEP_BASE_URL", "https://api.holysheep.ai/v1")
@dataclass
class OrderBookSnapshot:
"""Represents a single order book snapshot with bid/ask levels."""
exchange: str
symbol: str
timestamp: int # Unix milliseconds
bids: List[tuple] # [(price, quantity), ...]
asks: List[tuple] # [(price, quantity), ...]
def spread(self) -> float:
"""Calculate bid-ask spread in absolute terms."""
if self.asks and self.bids:
return float(self.asks[0][0]) - float(self.bids[0][0])
return 0.0
def mid_price(self) -> float:
"""Calculate mid-price (best bid + best ask) / 2."""
if self.asks and self.bids:
return (float(self.asks[0][0]) + float(self.bids[0][0])) / 2
return 0.0
def depth(self, levels: int = 25) -> Dict:
"""Calculate cumulative depth up to N levels."""
bid_depth = sum(float(q) for _, q in self.bids[:levels])
ask_depth = sum(float(q) for _, q in self.asks[:levels])
return {"bid_depth": bid_depth, "ask_depth": ask_depth}
async def fetch_historical_orderbook(
session: aiohttp.ClientSession,
exchange: str,
symbol: str,
start_time: int,
end_time: int,
depth: int = 25
) -> List[OrderBookSnapshot]:
"""
Fetch historical order book snapshots from HolySheep AI Tardis relay.
Args:
session: aiohttp ClientSession for connection pooling
exchange: Exchange name (binance, bybit, okx, deribit)
symbol: Trading pair symbol (e.g., BTC-USDT)
start_time: Start timestamp in Unix milliseconds
end_time: End timestamp in Unix milliseconds
depth: Number of price levels to include (default 25)
Returns:
List of OrderBookSnapshot objects sorted by timestamp
"""
url = f"{BASE_URL}/tardis/historical/orderbook"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"X-Request-ID": f"snapshot-fetch-{int(time.time() * 1000)}"
}
payload = {
"exchange": exchange,
"symbol": symbol,
"start_time": start_time,
"end_time": end_time,
"depth": depth,
"format": "normalized" # Use HolySheep normalized schema
}
snapshots = []
page_token = None
# Paginate through results - API returns max 10,000 messages per page
while True:
if page_token:
payload["page_token"] = page_token
async with session.post(url, headers=headers, json=payload) as response:
if response.status == 429:
# Rate limited - implement exponential backoff
retry_after = int(response.headers.get("Retry-After", 5))
print(f"Rate limited. Waiting {retry_after}s before retry...")
await asyncio.sleep(retry_after)
continue
if response.status != 200:
error_body = await response.text()
raise RuntimeError(
f"API request failed: {response.status} - {error_body}"
)
data = await response.json()
for msg in data.get("messages", []):
if msg["type"] == "snapshot":
snapshot = OrderBookSnapshot(
exchange=msg["exchange"],
symbol=msg["symbol"],
timestamp=msg["timestamp"],
bids=[(b["price"], b["quantity"]) for b in msg["bids"]],
asks=[(a["price"], a["quantity"]) for a in msg["asks"]]
)
snapshots.append(snapshot)
# Check for next page
page_token = data.get("next_page_token")
if not page_token:
break
# Respect API rate limits - 100 requests per minute on standard tier
await asyncio.sleep(0.6)
return sorted(snapshots, key=lambda x: x.timestamp)
async def main():
"""Example: Fetch BTC-USDT perpetual order book snapshots for 1 hour."""
# Configure time range: last 1 hour from now
end_time = int(datetime.now().timestamp() * 1000)
start_time = end_time - (60 * 60 * 1000) # 1 hour ago
print(f"Fetching order book snapshots from {datetime.fromtimestamp(start_time/1000)}")
print(f"To: {datetime.fromtimestamp(end_time/1000)}")
async with aiohttp.ClientSession() as session:
snapshots = await fetch_historical_orderbook(
session=session,
exchange="binance",
symbol="BTC-USDT",
start_time=start_time,
end_time=end_time,
depth=25
)
print(f"\nRetrieved {len(snapshots)} snapshots")
if snapshots:
# Analyze first, middle, and last snapshots
for idx in [0, len(snapshots)//2, -1]:
snap = snapshots[idx]
print(f"\nSnapshot at {datetime.fromtimestamp(snap.timestamp/1000)}:")
print(f" Best Bid: {snap.bids[0][0]} @ {snap.bids[0][1]}")
print(f" Best Ask: {snap.asks[0][0]} @ {snap.asks[0][1]}")
print(f" Spread: {snap.spread():.2f}")
depth = snap.depth(10)
print(f" Depth (10 levels): Bid={depth['bid_depth']:.4f}, Ask={depth['ask_depth']:.4f}")
if __name__ == "__main__":
asyncio.run(main())
This implementation handles several critical concerns. First, it uses connection pooling via aiohttp.ClientSession to amortize TCP handshake overhead across multiple requests. Second, it implements pagination to handle large result sets—the API returns a maximum of 10,000 messages per page, so any historical query spanning more than a few minutes will require multiple pages. Third, it includes basic rate limit handling with exponential backoff, which is essential when your pipeline scales to hundreds of concurrent requests.
Real-Time Order Book Streaming via WebSocket
While the REST API excels at bulk historical retrieval, real-time applications require WebSocket streaming. HolySheep AI's WebSocket endpoint delivers order book updates with <50ms latency from exchange to your application, making it suitable for live trading strategies, monitoring dashboards, and real-time analytics.
import os
import json
import asyncio
import websockets
from websockets.client import WebSocketClientProtocol
from typing import Callable, Optional
import threading
from queue import Queue, Empty
API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
BASE_URL = os.getenv("HOLYSHEEP_BASE_URL", "https://api.holysheep.ai/v1")
class OrderBookManager:
"""
Manages real-time order book state with incremental update processing.
This class maintains a full order book state and processes incremental
updates from the WebSocket stream, calculating derived metrics like
spread, mid-price, and volume-weighted metrics in real time.
"""
def __init__(self, symbol: str):
self.symbol = symbol
self.bids = {} # price -> quantity
self.asks = {} # price -> quantity
self.last_update_id: Optional[int] = None
self.message_count = 0
self.update_queue = Queue(maxsize=10000)
def process_snapshot(self, snapshot: dict):
"""Initialize order book from snapshot message."""
self.bids = {
float(b["price"]): float(b["quantity"])
for b in snapshot.get("bids", [])
if b["quantity"] > 0
}
self.asks = {
float(a["price"]): float(a["quantity"])
for a in snapshot.get("asks", [])
if a["quantity"] > 0
}
self.last_update_id = snapshot.get("update_id")
self.message_count += 1
def process_update(self, update: dict):
"""Apply incremental order book update."""
self.last_update_id = update.get("update_id")
# Process bid updates
for bid in update.get("b", []):
price, quantity = float(bid[0]), float(bid[1])
if quantity == 0:
self.bids.pop(price, None)
else:
self.bids[price] = quantity
# Process ask updates
for ask in update.get("a", []):
price, quantity = float(ask[0]), float(ask[1])
if quantity == 0:
self.asks.pop(price, None)
else:
self.asks[price] = quantity
self.message_count += 1
# Calculate and queue derived metrics
metrics = self.calculate_metrics()
try:
self.update_queue.put_nowait({
"timestamp": update.get("timestamp"),
"update_id": self.last_update_id,
"metrics": metrics
})
except:
pass # Queue full - skip this update
def calculate_metrics(self) -> dict:
"""Calculate real-time order book metrics."""
if not self.bids or not self.asks:
return {}
sorted_bids = sorted(self.bids.items(), key=lambda x: -x[0])
sorted_asks = sorted(self.asks.items(), key=lambda x: x[0])
best_bid = sorted_bids[0]
best_ask = sorted_asks[0]
spread = best_ask[0] - best_bid[0]
mid_price = (best_bid[0] + best_ask[0]) / 2
spread_bps = (spread / mid_price) * 10000 if mid_price > 0 else 0
# Calculate cumulative depth at various levels
def cumulative_depth(orders, levels):
return sum(qty for _, qty in orders[:levels])
return {
"best_bid": best_bid[0],
"best_bid_qty": best_bid[1],
"best_ask": best_ask[0],
"best_ask_qty": best_ask[1],
"spread": spread,
"spread_bps": round(spread_bps, 2),
"mid_price": mid_price,
"bid_depth_5": cumulative_depth(sorted_bids, 5),
"ask_depth_5": cumulative_depth(sorted_asks, 5),
"bid_depth_10": cumulative_depth(sorted_bids, 10),
"ask_depth_10": cumulative_depth(sorted_asks, 10),
"total_bid_levels": len(self.bids),
"total_ask_levels": len(self.asks)
}
def get_best_prices(self) -> tuple:
"""Return (best_bid, best_ask) tuple."""
if self.bids and self.asks:
return max(self.bids.keys()), min(self.asks.keys())
return None, None
async def stream_orderbook_updates(
exchange: str,
symbol: str,
callback: Optional[Callable] = None,
run_duration: Optional[int] = None
):
"""
Connect to HolySheep WebSocket and stream order book updates.
Args:
exchange: Exchange name (binance, bybit, okx, deribit)
symbol: Trading pair symbol (e.g., BTC-USDT)
callback: Optional async function called on each update
run_duration: Optional max run time in seconds
"""
# Build WebSocket URL with authentication
ws_url = f"{BASE_URL.replace('https://', 'wss://')}/tardis/ws"
headers = {
"Authorization": f"Bearer {API_KEY}"
}
ob_manager = OrderBookManager(symbol)
print(f"Connecting to {ws_url} for {exchange}:{symbol}")
try:
async with websockets.connect(ws_url, extra_headers=headers) as ws:
# Send subscription message
subscribe_msg = {
"action": "subscribe",
"channel": "orderbook",
"exchange": exchange,
"symbol": symbol,
"depth": 25,
"format": "normalized"
}
await ws.send(json.dumps(subscribe_msg))
print(f"Subscribed to {exchange}:{symbol} order book stream")
# Receive subscription confirmation
response = await asyncio.wait_for(ws.recv(), timeout=10)
print(f"Server response: {response}")
# Main message loop
start_time = asyncio.get_event_loop().time()
while True:
try:
# Apply timeout if duration specified
if run_duration:
remaining = start_time + run_duration - asyncio.get_event_loop().time()
if remaining <= 0:
break
message = await asyncio.wait_for(ws.recv(), timeout=min(remaining, 30))
else:
message = await ws.recv()
data = json.loads(message)
# Handle different message types
msg_type = data.get("type")
if msg_type == "snapshot":
ob_manager.process_snapshot(data)
print(f"[{data.get('timestamp')}] Snapshot received: "
f"Bids={len(data.get('bids', []))}, "
f"Asks={len(data.get('asks', []))}")
elif msg_type == "update":
ob_manager.process_update(data)
metrics = ob_manager.calculate_metrics()
if callback:
await callback(data, metrics)
else:
# Default: print every 100th update for monitoring
if ob_manager.message_count % 100 == 0:
print(f"[{data.get('timestamp')}] "
f"Spread={metrics.get('spread_bps', 0)}bps, "
f"Mid={metrics.get('mid_price', 0):.2f}, "
f"Depth10={metrics.get('bid_depth_10', 0):.4f}/"
f"{metrics.get('ask_depth_10', 0):.4f}")
except asyncio.TimeoutError:
# Heartbeat / timeout - continue loop
continue
except websockets.exceptions.ConnectionClosed as e:
print(f"WebSocket connection closed: {e}")
except Exception as e:
print(f"Stream error: {e}")
raise
async def example_callback(data: dict, metrics: dict):
"""Example callback for processing order book updates."""
print(f"Update @ {metrics.get('mid_price', 0):.2f}: "
f"Spread {metrics.get('spread_bps', 0)}bps")
async def main():
"""Run order book stream for 60 seconds as a demonstration."""
print("=" * 60)
print("HolySheep AI - Tardis Order Book Streaming Demo")
print("=" * 60)
await stream_orderbook_updates(
exchange="binance",
symbol="BTC-USDT",
callback=example_callback,
run_duration=60 # Run for 60 seconds
)
print("\nStream completed.")
if __name__ == "__main__":
asyncio.run(main())
The WebSocket implementation introduces several advanced patterns that you will need in production systems. The OrderBookManager class maintains local order book state and processes incremental updates, which is far more efficient than reconstructing the full book from every update message. The derived metrics calculation—including spread in basis points and cumulative depth at multiple levels—happens in real time without additional API calls.
Reconstructing Historical Order Book Sequences
For backtesting and research applications, you often need more than isolated snapshots—you need a complete, ordered sequence of order book states over a time period. The following code builds a replay engine that processes historical messages in order, maintaining accurate order book state throughout.
import os
import json
import asyncio
import aiohttp
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Optional
from datetime import datetime
from collections import defaultdict
import heapq
API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
BASE_URL = os.getenv("HOLYSHEEP_BASE_URL", "https://api.holysheep.ai/v1")
@dataclass
class OrderBookState:
"""Immutable order book state at a point in time."""
timestamp: int
bids: List[Tuple[float, float]] # Sorted descending by price
asks: List[Tuple[float, float]] # Sorted ascending by price
sequence: int
@property
def spread(self) -> float:
if self.asks and self.bids:
return self.asks[0][0] - self.bids[0][0]
return float('inf')
@property
def mid_price(self) -> float:
if self.asks and self.bids:
return (self.asks[0][0] + self.bids[0][0]) / 2
return 0.0
class OrderBookReplayer:
"""
Replays historical order book data and reconstructs complete order book sequences.
This class handles both snapshot + update replay patterns, ensuring the order book
state is always consistent and accurately reflects market microstructure at each
point in time.
"""
def __init__(self, exchange: str, symbol: str):
self.exchange = exchange
self.symbol = symbol
self.bids = {} # price -> quantity
self.asks = {} # price -> quantity
self.last_update_id = 0
self.sequence = 0
self.states = []
self.pending_updates = {} # update_id -> updates
def apply_snapshot(self, snapshot: dict):
"""Reset and apply a snapshot message."""
self.bids = {
float(b["price"]): float(b["quantity"])
for b in snapshot.get("bids", [])
}
self.asks = {
float(a["price"]): float(a["quantity"])
for a in snapshot.get("asks", [])
}
self.last_update_id = snapshot.get("update_id", 0)
self._capture_state(snapshot.get("timestamp", 0))
def apply_update(self, update: dict):
"""Apply an incremental update, handling out-of-order messages."""
update_id = update.get("update_id", 0)
timestamp = update.get("timestamp", 0)
# Buffer updates that arrive before snapshot (should not happen with HolySheep)
if update_id <= self.last_update_id and self.last_update_id > 0:
return
# Apply bid updates
for bid in update.get("bids", update.get("b", [])):
price, quantity = float(bid[0] if isinstance(bid, list) else bid["price"]), \
float(bid[1] if isinstance(bid, list) else bid["quantity"])
if quantity == 0:
self.bids.pop(price, None)
else:
self.bids[price] = quantity
# Apply ask updates
for ask in update.get("asks", update.get("a", [])):
price, quantity = float(ask[0] if isinstance(ask, list) else ask["price"]), \
float(ask[1] if isinstance(ask, list) else ask["quantity"])
if quantity == 0:
self.asks.pop(price, None)
else:
self.asks[price] = quantity
self.last_update_id = update_id
self._capture_state(timestamp)
def _capture_state(self, timestamp: int):
"""Capture current order book state as an immutable snapshot."""
sorted_bids = sorted(self.bids.items(), key=lambda x: -x[0])
sorted_asks = sorted(self.asks.items(), key=lambda x: x[0])
self.states.append(OrderBookState(
timestamp=timestamp,
bids=[(p, q) for p, q in sorted_bids if q > 0],
asks=[(p, q) for p, q in sorted_asks if q > 0],
sequence=self.sequence
))
self.sequence += 1
def get_state_at(self, timestamp: int) -> Optional[OrderBookState]:
"""Get the order book state closest to but not after the given timestamp."""
for state in reversed(self.states):
if state.timestamp <= timestamp:
return state
return None
def calculate_vwap_impact(self, side: str, volume: float) -> float:
"""
Calculate volume-weighted average price impact for a given trade volume.
Args:
side: 'buy' or 'sell'
volume: Volume to calculate impact for
Returns:
Volume-weighted average execution price
"""
if side == 'buy':
levels = sorted(self.asks.items(), key=lambda x: x[0])
else:
levels = sorted(self.bids.items(), key=lambda x: -x[0])
remaining_volume = volume
total_cost = 0.0
for price, qty in levels:
if remaining_volume <= 0:
break
executed = min(remaining_volume, qty)
total_cost += executed * price
remaining_volume -= executed
if volume > remaining_volume:
return total_cost / (volume - remaining_volume)
return 0.0
async def replay_historical_sequence(
exchange: str,
symbol: str,
start_time: int,
end_time: int
) -> OrderBookReplayer:
"""
Fetch and replay a complete historical order book sequence.
Returns an OrderBookReplayer with fully reconstructed state history.
"""
replayer = OrderBookReplayer(exchange, symbol)
url = f"{BASE_URL}/tardis/historical/sequence"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"exchange": exchange,
"symbol": symbol,
"start_time": start_time,
"end_time": end_time,
"channels": ["orderbook"],
"format": "normalized",
"include_raw": False
}
print(f"Fetching historical sequence: {datetime.fromtimestamp(start_time/1000)} -> "
f"{datetime.fromtimestamp(end_time/1000)}")
async with aiohttp.ClientSession() as session:
page_token = None
total_messages = 0
while True:
if page_token:
payload["page_token"] = page_token
async with session.post(url, headers=headers, json=payload) as response:
if response.status != 200:
error = await