I still remember the Sunday morning in January when my production trading system silently started bleeding money. The Order Book was there—visually fine, prices looked reasonable—but my signal was off by a consistent 15-20%. After 6 hours of debugging, I found it: I was using Level 1 bid/ask instead of proper L2 depth aggregation. The fix took 20 minutes, but cost me $4,200 in slippage. That experience taught me why Order Book imbalance factors built on proper L2 data are non-negotiable for serious alpha generation. Today, I'm going to show you exactly how to build production-grade OBI (Order Book Imbalance) signals using Tardis.dev data, and why HolySheep AI should be your inference backbone for the ML models that consume these signals.
What Is Order Book Imbalance (OBI)?
Order Book Imbalance measures the directional pressure between buy and sell sides of the limit order book. At its core, OBI quantifies "who controls the near-term price" by comparing the volume resting on bids versus asks within a specified price range or depth level.
The canonical formula:
OBI = (BidVolume - AskVolume) / (BidVolume + AskVolume)
Values range from -1 (all sell pressure) to +1 (all buy pressure). A reading near 0 suggests equilibrium, while readings above 0.3 or below -0.3 often precede short-term mean reversion or momentum continuation depending on your timeframe.
Why Tardis.dev L2 Data?
Tardis.dev provides normalized, real-time Level 2 order book snapshots and incremental updates for 30+ exchanges including Binance, Bybit, OKX, and Deribit. Unlike some aggregators that resample or delay data, Tardis delivers:
- Sub-100ms latency on institutional-grade infrastructure
- Full order book depth with price levels and quantities
- Snapshot + delta updates enabling efficient state management
- Consistent schema across exchanges
Setting Up the Data Pipeline
First, let's establish the infrastructure. You'll need a Tardis.dev subscription for L2 data, and an inference endpoint for your ML model. Here's the complete setup:
# Install required packages
pip install tardis-client websockets asyncio aiohttp pandas numpy
tardis-client version 1.3.0+ required for proper L2 support
Verify installation
python -c "import tardis; print(tardis.__version__)"
# Full Order Book Imbalance Signal Pipeline
import asyncio
import json
from tardis_client import TardisClient, MessageType
import pandas as pd
import numpy as np
from datetime import datetime
class OrderBookImbalance:
def __init__(self, max_depth_levels=20):
self.max_depth_levels = max_depth_levels
self.bids = {} # price -> quantity
self.asks = {} # price -> quantity
self.ob_history = []
def apply_snapshot(self, data):
"""Handle full order book snapshot"""
self.bids = {}
self.asks = {}
for entry in data.get('bids', []):
self.bids[float(entry['price'])] = float(entry['quantity'])
for entry in data.get('asks', []):
self.asks[float(entry['price'])] = float(entry['quantity'])
def apply_delta(self, data):
"""Apply incremental order book update"""
for entry in data.get('bids', []):
price = float(entry['price'])
qty = float(entry['quantity'])
if qty == 0:
self.bids.pop(price, None)
else:
self.bids[price] = qty
for entry in data.get('asks', []):
price = float(entry['price'])
qty = float(entry['quantity'])
if qty == 0:
self.asks.pop(price, None)
else:
self.asks[price] = qty
def calculate_obi(self, spread_pct=0.001):
"""
Calculate multi-level Order Book Imbalance
spread_pct: only consider levels within X% of mid price
"""
if not self.bids or not self.asks:
return None
best_bid = max(self.bids.keys())
best_ask = min(self.asks.keys())
mid_price = (best_bid + best_ask) / 2
# Filter by spread threshold
price_range = mid_price * spread_pct
bid_volume = sum(
qty for price, qty in self.bids.items()
if price >= mid_price - price_range
)
ask_volume = sum(
qty for price, qty in self.asks.items()
if price <= mid_price + price_range
)
total_volume = bid_volume + ask_volume
if total_volume == 0:
return 0.0
obi = (bid_volume - ask_volume) / total_volume
# Store for later analysis
self.ob_history.append({
'timestamp': datetime.utcnow().isoformat(),
'obi': obi,
'bid_vol': bid_volume,
'ask_vol': ask_volume,
'mid_price': mid_price,
'best_bid': best_bid,
'best_ask': best_ask
})
return obi
async def main():
tardis = TardisClient()
# Binance BTC/USDT perpetual L2 data
exchange_name = "binance"
symbol = "BTCUSDT"
obi_tracker = OrderBookImbalance(max_depth_levels=20)
async for entry in tardis.subscribe(
exchange=exchange_name,
symbols=[symbol],
channels=[MessageType.l2_orderbook]
):
if entry.type == MessageType.snapshot:
obi_tracker.apply_snapshot(entry.data)
elif entry.type == MessageType.delta:
obi_tracker.apply_delta(entry.data)
obi = obi_tracker.calculate_obi(spread_pct=0.002)
if obi is not None:
print(f"OBI: {obi:.4f} | Mid: {obi_tracker.ob_history[-1]['mid_price']}")
# Send to your ML model for inference
if len(obi_tracker.ob_history) >= 100:
features = prepare_features(obi_tracker.ob_history)
# Next section shows inference integration
def prepare_features(history):
"""Feature engineering for ML model"""
df = pd.DataFrame(history[-100:])
features = {
'obi_current': df['obi'].iloc[-1],
'obi_mean_10': df['obi'].tail(10).mean(),
'obi_std_10': df['obi'].tail(10).std(),
'obi_ma_ratio': df['obi'].iloc[-1] / (df['obi'].mean() + 1e-8),
'volume_imbalance': (df['bid_vol'].iloc[-1] - df['ask_vol'].iloc[-1]) /
(df['bid_vol'].iloc[-1] + df['ask_vol'].iloc[-1] + 1e-8),
'price_momentum': (df['mid_price'].iloc[-1] / df['mid_price'].iloc[0]) - 1
}
return features
if __name__ == "__main__":
asyncio.run(main())
HolySheep AI Integration for Real-Time Inference
Once you've computed OBI features, you need a fast inference endpoint. HolySheep AI delivers <50ms latency at $1 per dollar (saves 85%+ versus the ¥7.3 pricing common elsewhere), with WeChat and Alipay supported for Chinese users. Here's the complete inference integration:
# HolySheep AI Inference for OBI-based signals
import aiohttp
import json
import asyncio
from typing import