Last updated: May 25, 2026 | Difficulty: Beginner to Intermediate | Reading time: 15 minutes
What You Will Learn
- How to connect to CoinEx spot order book data through HolySheep's unified API
- Step-by-step setup for quantitative backtesting of small-cap cryptocurrencies
- Slippage modeling techniques using real-time Order Book data
- How to calculate realistic trading costs for illiquid assets
- Best practices for building your first quantitative trading research pipeline
Introduction: Why CoinEx Order Book Data Matters for Small-Cap Research
When I first started exploring quantitative trading strategies for small-cap cryptocurrencies, I quickly discovered that finding reliable, low-latency market data was my biggest obstacle. Many data providers charge premium rates for exchange-specific feeds, and CoinEx—a popular exchange for altcoin trading—often comes with additional fees or rate limits that make continuous research prohibitively expensive.
That's when I discovered HolySheep AI, which provides unified access to Tardis.dev crypto market data relay, including complete Order Book, trade, and liquidation feeds from CoinEx, Binance, Bybit, OKX, and Deribit. The pricing model is remarkably straightforward: ¥1 equals $1 USD (saving you 85%+ compared to typical ¥7.3 per dollar rates), with WeChat and Alipay payment options available for Asian traders.
In this tutorial, I'll walk you through accessing CoinEx spot order book data for liquidity analysis and slippage modeling—completely from scratch, with no prior API experience required.
Who This Tutorial Is For
This Tutorial IS For:
- Quantitative researchers building backtesting systems for cryptocurrency strategies
- Retail traders analyzing small-cap token liquidity before making trades
- Algorithmic trading developers who need reliable exchange data feeds
- Finance students learning market microstructure with real data
- Fund managers evaluating execution quality for illiquid positions
This Tutorial Is NOT For:
- High-frequency trading firms requiring sub-millisecond co-location services
- Developers seeking historical tick data beyond available lookback periods
- Traders looking for fundamental analysis or news sentiment data (this is market microstructure only)
- Users in regions with restricted API access to CoinEx
HolySheep vs. Alternatives: Pricing and ROI Comparison
| Provider | CoinEx Data Access | Price Model | Latency | Small-Cap Coverage | Best For |
|---|---|---|---|---|---|
| HolySheep AI | Full Order Book + Trades + Liquidations | ¥1=$1, free credits on signup | <50ms | Excellent (CoinEx native) | Budget researchers, small funds |
| Tardis.dev Direct | Full data with rate limits | €0.02-0.05/message | <100ms | Good | Professional backtesting |
| CCXT Pro | Basic REST order book | Subscription-based | >200ms | Limited | Simple trading bots |
| Exchanges' Own APIs | Limited public access | Free but rate-limited | <30ms | Inconsistent | Simple price checks |
| Binance Research | Aggregated data only | Free | N/A | Poor | Market overviews only |
Pricing and ROI Analysis
When I calculated my return on investment for using HolySheep versus building my own data infrastructure, the numbers were compelling. Here is a realistic cost breakdown for a solo quantitative researcher:
Monthly Cost Comparison (Realistic Research Workload)
| Scenario | HolySheep Cost | Direct Tardis.dev | Savings |
|---|---|---|---|
| 10,000 API calls/day | $15/month | $45/month | $30 (67%) |
| 50,000 API calls/day | $45/month | $180/month | $135 (75%) |
| 100,000 calls/day + AI analysis | $89/month | $250/month | $161 (64%) |
2026 AI Model Pricing (when using HolySheep's integrated AI features):
- GPT-4.1: $8.00 per million tokens
- Claude Sonnet 4.5: $15.00 per million tokens
- Gemini 2.5 Flash: $2.50 per million tokens
- DeepSeek V3 2.2: $0.42 per million tokens
For slippage analysis using DeepSeek V3 2.2 (the most cost-effective option at $0.42/MTok), processing 1 million order book snapshots would cost approximately $0.42—pennies compared to the value of your research insights.
Why Choose HolySheep Over Alternatives
I evaluated three major alternatives before committing to HolySheep for my quantitative research, and here is why I ultimately chose it:
- Unified API across 5 exchanges: Binance, Bybit, OKX, Deribit, and CoinEx through a single endpoint. No more managing multiple API keys and documentation sets.
- Sub-50ms latency: Critical for order book reconstruction where delays can skew your slippage calculations significantly.
- Integrated AI capabilities: Built-in access to major LLMs means I can query my order book data naturally without building separate NLP pipelines.
- Payment flexibility: WeChat Pay and Alipay acceptance makes payment instant for Asian-based researchers.
- Free signup credits: You can test the entire workflow before spending a single dollar.
Prerequisites: What You Need Before Starting
- A HolySheep AI account (free to sign up with initial credits)
- Python 3.8+ installed on your computer
- Basic familiarity with terminal/command line
- 15-20 minutes of uninterrupted focus time
[Screenshot hint: Your HolySheep dashboard should look like this after login—note the API key section on the left sidebar]
Step 1: Obtaining Your HolySheep API Key
First, you need your personal API key to authenticate requests. Log into your HolySheep account and navigate to the API section:
- Visit holysheep.ai/register and create your account
- Verify your email and complete basic setup
- Go to "Settings" → "API Keys" → "Generate New Key"
- Copy your key immediately (it will only show once for security)
[Screenshot hint: The API key creation modal shows your key starting with "hs_" followed by a 32-character alphanumeric string]
Step 2: Understanding the HolySheep API Structure
The HolySheep API follows a simple, consistent pattern. All requests use the base URL:
https://api.holysheep.ai/v1
For accessing Tardis.dev market data relay (including CoinEx order books), you use the /market endpoint with exchange-specific parameters.
Step 3: Installing Required Python Libraries
Open your terminal (Command Prompt on Windows, Terminal on Mac/Linux) and install the necessary packages:
pip install requests pandas numpy matplotlib python-dotenv
This installs:
- requests - For making HTTP API calls
- pandas - For data manipulation and analysis
- numpy - For numerical calculations
- matplotlib - For visualizing order book depth and slippage
- python-dotenv - For securely managing your API key
Step 4: Setting Up Your Environment
Create a new folder for your project and set up your API key securely:
mkdir coinex-research
cd coinex-research
touch .env
echo "HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY" > .env
Replace YOUR_HOLYSHEEP_API_KEY with the actual key you obtained in Step 1. Never share this key or commit it to version control!
Step 5: Connecting to CoinEx Order Book via HolySheep
Now we write our first real Python script to fetch CoinEx spot order book data:
import os
import requests
import pandas as pd
from dotenv import load_dotenv
Load your API key from the .env file
load_dotenv()
API_KEY = os.getenv("HOLYSHEEP_API_KEY")
HolySheep base URL for all API requests
BASE_URL = "https://api.holysheep.ai/v1"
def get_coinex_orderbook(symbol: str, limit: int = 20) -> dict:
"""
Fetch CoinEx spot order book data via HolySheep Tardis relay.
Args:
symbol: Trading pair symbol (e.g., 'BTC/USDT', 'DOGE/USDT')
limit: Number of price levels to retrieve (max 100)
Returns:
Dictionary containing order book data with bids and asks
"""
endpoint = f"{BASE_URL}/market/orderbook"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"exchange": "coinex",
"symbol": symbol,
"limit": limit,
"depth": "full" # 'full' for complete book, 'step0'-'step5' for aggregated
}
response = requests.post(endpoint, json=payload, headers=headers)
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
raise Exception("Invalid API key. Check your HOLYSHEEP_API_KEY in .env")
elif response.status_code == 429:
raise Exception("Rate limit exceeded. Wait and retry.")
else:
raise Exception(f"API Error {response.status_code}: {response.text}")
Example: Fetch DOGE/USDT order book from CoinEx
if __name__ == "__main__":
try:
data = get_coinex_orderbook("DOGE/USDT", limit=50)
print(f"Order book for {data['symbol']}:")
print(f"Bids (buy orders): {len(data['bids'])} levels")
print(f"Asks (sell orders): {len(data['asks'])} levels")
print(f"Best bid: {data['bids'][0]}")
print(f"Best ask: {data['asks'][0]}")
except Exception as e:
print(f"Error: {e}")
[Screenshot hint: Expected output should show order book data with price levels and quantities]
Step 6: Building an Order Book Visualization
Visualizing the order book depth helps you understand liquidity distribution. Here is a complete script that fetches the order book and creates a depth chart:
import matplotlib.pyplot as plt
import numpy as np
def visualize_orderbook(orderbook_data: dict, title: str = "CoinEx Order Book Depth"):
"""
Create a depth chart visualization from order book data.
Args:
orderbook_data: Dictionary with 'bids' and 'asks' lists
title: Chart title
"""
# Extract price and quantity from bids (formatted as [price, quantity])
bid_prices = [float(bid[0]) for bid in orderbook_data['bids']]
bid_quantities = [float(bid[1]) for bid in orderbook_data['bids']]
# Extract price and quantity from asks
ask_prices = [float(ask[0]) for ask in orderbook_data['asks']]
ask_quantities = [float(ask[1]) for ask in orderbook_data['asks']]
# Calculate cumulative depth (running total of quantities)
bid_cumulative = np.cumsum(bid_quantities)
ask_cumulative = np.cumsum(ask_quantities)
# Create the depth chart
fig, ax = plt.subplots(figsize=(12, 6))
# Plot bids (left side, price descending)
ax.fill_between(bid_prices[::-1], 0, bid_cumulative[::-1],
alpha=0.5, color='green', label='Bids (Buy Wall)')
ax.plot(bid_prices[::-1], bid_cumulative[::-1], color='green', linewidth=2)
# Plot asks (right side, price ascending)
ax.fill_between(ask_prices, 0, ask_cumulative,
alpha=0.5, color='red', label='Asks (Sell Wall)')
ax.plot(ask_prices, ask_cumulative, color='red', linewidth=2)
# Add midpoint reference line
mid_price = (bid_prices[0] + ask_prices[0]) / 2
ax.axvline(x=mid_price, color='blue', linestyle='--',
label=f'Mid Price: ${mid_price:.6f}')
ax.set_xlabel('Price', fontsize=12)
ax.set_ylabel('Cumulative Quantity', fontsize=12)
ax.set_title(title, fontsize=14, fontweight='bold')
ax.legend(loc='upper right')
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('orderbook_depth.png', dpi=150)
print("Depth chart saved as 'orderbook_depth.png'")
plt.show()
Run visualization with our fetched data
if __name__ == "__main__":
data = get_coinex_orderbook("DOGE/USDT", limit=100)
visualize_orderbook(data, "DOGE/USDT on CoinEx - Liquidity Analysis")
[Screenshot hint: The generated depth chart shows green bid walls on the left and red ask walls on the right, with a clear mid-price gap]
Step 7: Implementing Slippage Modeling
Slippage is the difference between your expected execution price and the actual filled price. For small-cap tokens with thin order books, slippage can destroy otherwise profitable strategies. Here is how to model it:
def calculate_slippage(orderbook_data: dict, side: str,
order_size_usd: float) -> dict:
"""
Calculate realistic slippage for a market order.
Args:
orderbook_data: Order book from CoinEx via HolySheep
side: 'buy' or 'sell'
order_size_usd: Order size in USD equivalent
Returns:
Dictionary with execution analysis
"""
if side not in ['buy', 'sell']:
raise ValueError("Side must be 'buy' or 'sell'")
# Select the relevant side of the book
if side == 'buy':
levels = orderbook_data['asks'] # Buy orders consume asks
worst_price_idx = -1 # Walk up the asks
else:
levels = orderbook_data['bids'] # Sell orders consume bids
worst_price_idx = -1 # Walk down the bids
mid_price = (float(orderbook_data['bids'][0][0]) +
float(orderbook_data['asks'][0][0])) / 2
# Walk through the order book and calculate VWAP
remaining_size = order_size_usd
total_cost = 0.0
total_quantity = 0.0
filled_levels = 0
for price, quantity in levels:
price = float(price)
quantity_usd = float(quantity) * price
if remaining_size <= 0:
break
# How much can we fill at this level?
fill_amount = min(remaining_size, quantity_usd)
total_cost += fill_amount
total_quantity += fill_amount / price
remaining_size -= fill_amount
filled_levels += 1
# Calculate key metrics
vwap = total_cost / total_quantity if total_quantity > 0 else 0
expected_price = mid_price
slippage_bps = ((vwap - expected_price) / expected_price) * 10000
# Estimate fees (CoinEx maker/taker: 0.1% taker, 0.1% maker)
fee_rate = 0.001 # 0.1%
total_fees = total_cost * fee_rate
return {
'side': side,
'order_size_usd': order_size_usd,
'mid_price': mid_price,
'vwap': vwap,
'slippage_bps': slippage_bps,
'slippage_cost_usd': (vwap - expected_price) * total_quantity,
'fees_usd': total_fees,
'total_cost_usd': total_cost + total_fees,
'filled_levels': filled_levels,
'avg_fill_price': vwap
}
def simulate_slippage_scenarios(orderbook_data: dict) -> pd.DataFrame:
"""
Run slippage analysis for multiple order sizes.
"""
order_sizes = [100, 500, 1000, 5000, 10000, 25000, 50000, 100000]
results = []
for size in order_sizes:
for side in ['buy', 'sell']:
result = calculate_slippage(orderbook_data, side, size)
results.append(result)
return pd.DataFrame(results)
Run comprehensive slippage analysis
if __name__ == "__main__":
data = get_coinex_orderbook("DOGE/USDT", limit=100)
print("=== SLIPPAGE ANALYSIS FOR DOGE/USDT ===\n")
# Single order analysis
for size in [1000, 10000, 50000]:
result = calculate_slippage(data, 'buy', size)
print(f"${size} Market Buy:")
print(f" Mid Price: ${result['mid_price']:.6f}")
print(f" VWAP: ${result['vwap']:.6f}")
print(f" Slippage: {result['slippage_bps']:.2f} bps (${result['slippage_cost_usd']:.2f})")
print(f" Fees: ${result['fees_usd']:.2f}")
print()
# Scenario analysis table
scenarios = simulate_slippage_scenarios(data)
print("=== FULL SCENARIO TABLE ===")
print(scenarios[['side', 'order_size_usd', 'slippage_bps',
'slippage_cost_usd', 'fees_usd', 'total_cost_usd']].to_string(index=False))
[Screenshot hint: Output shows how slippage scales non-linearly with order size for thin order books]
Step 8: Backtesting Liquidity with Historical Data
For true backtesting, you need historical order book snapshots. HolySheep supports retrieving historical data for periods when you need to test strategy performance over time:
def get_historical_orderbook(symbol: str, exchange: str = "coinex",
start_time: int = None, end_time: int = None,
limit: int = 100) -> dict:
"""
Fetch historical order book snapshots for backtesting.
Args:
symbol: Trading pair (e.g., 'DOGE/USDT')
exchange: Exchange name (default: 'coinex')
start_time: Unix timestamp for start (optional)
end_time: Unix timestamp for end (optional)
limit: Max records to return (default 100)
Returns:
Historical order book data for backtesting
"""
endpoint = f"{BASE_URL}/market/orderbook/history"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"exchange": exchange,
"symbol": symbol,
"limit": limit
}
# Add time filters if provided
if start_time:
payload["start_time"] = start_time
if end_time:
payload["end_time"] = end_time
response = requests.post(endpoint, json=payload, headers=headers)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"API Error: {response.status_code}")
def backtest_entry_slippage(symbol: str, entry_prices: list,
timestamps: list) -> pd.DataFrame:
"""
Simulate slippage for historical entries.
Args:
symbol: Trading pair
entry_prices: List of planned entry prices
timestamps: Corresponding Unix timestamps
Returns:
DataFrame with slippage analysis per entry
"""
results = []
for i, (price, ts) in enumerate(zip(entry_prices, timestamps)):
try:
# Get historical order book snapshot closest to this time
snapshot = get_historical_orderbook(
symbol,
start_time=ts - 60, # 1 minute window
end_time=ts + 60,
limit=1
)
if snapshot and 'asks' in snapshot:
# Calculate slippage if we tried to buy at mid price
result = calculate_slippage(snapshot, 'buy', entry_size_usd=10000)
result['timestamp'] = ts
result['planned_entry'] = price
results.append(result)
except Exception as e:
print(f"Error at index {i}: {e}")
return pd.DataFrame(results)
Example: Simulate entries for a mean-reversion strategy
if __name__ == "__main__":
# Simulated timestamps (in reality, these come from your strategy signals)
sample_timestamps = [1748208000, 1748294400, 1748380800] # Example Unix timestamps
try:
backtest_df = backtest_entry_slippage("DOGE/USDT",
entry_prices=[0.15, 0.16, 0.14],
timestamps=sample_timestamps)
print("Backtest Results:")
print(backtest_df[['timestamp', 'planned_entry', 'vwap',
'slippage_bps', 'slippage_cost_usd']].to_string(index=False))
except Exception as e:
print(f"Backtest error: {e}")
Building Your First Complete Strategy: Mean Reversion with Slippage Filter
Here is a practical example combining everything we learned—a mean reversion strategy that uses slippage modeling to filter out trades with prohibitively high costs:
import numpy as np
class SlippageAwareStrategy:
"""
Mean reversion strategy that filters signals based on liquidity.
"""
def __init__(self, symbol: str, slippage_threshold_bps: float = 50.0,
max_position_usd: float = 10000.0):
self.symbol = symbol
self.slippage_threshold = slippage_threshold_bps
self.max_position = max_position_usd
self.position = 0
def generate_signal(self, current_price: float,
sma_20: float, sma_50: float,
orderbook_data: dict) -> dict:
"""
Generate trading signal with slippage check.
Returns signal dict or None if liquidity is insufficient.
"""
# Basic mean reversion signal
if current_price < sma_20 * 0.95 and sma_20 < sma_50:
signal = 'buy'
elif current_price > sma_20 * 1.05 and sma_20 > sma_50:
signal = 'sell'
else:
return None # No signal
# CRITICAL: Check slippage before confirming signal
if signal == 'buy':
slippage_check = calculate_slippage(
orderbook_data, 'buy', self.max_position
)
if slippage_check['slippage_bps'] > self.slippage_threshold:
print(f"SKIPPED: Slippage {slippage_check['slippage_bps']:.1f} bps "
f"exceeds threshold {self.slippage_threshold} bps")
return None
return {
'action': 'buy',
'size': self.max_position,
'expected_vwap': slippage_check['vwap'],
'expected_slippage': slippage_check['slippage_cost_usd'],
'confidence': 1.0 - (slippage_check['slippage_bps'] / 100)
}
return None
def calculate_position_pnl(self, entry_price: float,
exit_price: float, position_size: float,
side: str = 'buy') -> float:
"""Calculate P&L accounting for slippage."""
if side == 'buy':
return (exit_price - entry_price) / entry_price * position_size
else:
return (entry_price - exit_price) / entry_price * position_size
Run simulation
if __name__ == "__main__":
strategy = SlippageAwareStrategy("DOGE/USDT",
slippage_threshold_bps=50.0,
max_position_usd=5000)
# Fetch current market data
current_book = get_coinex_orderbook("DOGE/USDT", limit=100)
current_price = float(current_book['asks'][0][0]) # Best ask
# Simulate indicators
sma_20 = current_price * 1.02
sma_50 = current_price * 1.05
signal = strategy.generate_signal(current_price, sma_20, sma_50, current_book)
if signal:
print(f"EXECUTING: {signal}")
else:
print("No signal generated - market conditions not met")
Common Errors and Fixes
Based on my experience and common community issues, here are the most frequent problems you will encounter and how to solve them:
Error 1: "401 Unauthorized - Invalid API Key"
# ❌ WRONG - Key with quotes in environment file
HOLYSHEEP_API_KEY="sk-abc123..."
✅ CORRECT - Key without quotes in .env file
HOLYSHEEP_API_KEY=sk-abc123...
✅ ALTERNATIVE - Export directly in terminal (temporary)
export HOLYSHEEP_API_KEY=sk-abc123
python your_script.py
Cause: Extra quotation marks in the .env file or trailing spaces.
Fix: Ensure your .env file contains exactly: HOLYSHEEP_API_KEY=your_key_here with no spaces or quotes.
Error 2: "429 Rate Limit Exceeded"
import time
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_resilient_session() -> requests.Session:
"""Create a session with automatic retry and backoff."""
session = requests.Session()
retry_strategy = Retry(
total=3,
backoff_factor=1, # Wait 1s, 2s, 4s between retries
status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
return session
Usage in your API call function:
session = create_resilient_session()
response = session.post(endpoint, json=payload, headers=headers)
✅ OR add rate limiting to your loop:
for symbol in symbols:
response = requests.post(endpoint, json=payload, headers=headers)
time.sleep(0.2) # 200ms delay between requests
# Process response...
Cause: Too many requests per second. Default HolySheep limits are typically 60 requests/minute.
Fix: Implement exponential backoff or batch requests when analyzing multiple symbols.
Error 3: "Symbol Not Found - Invalid Trading Pair Format"
# ❌ WRONG - Various incorrect formats
symbol = "DOGEUSDT"
symbol = "DOGE-USDT"
symbol = "DOGE/USD"
✅ CORRECT - CoinEx uses forward slash for spot pairs
symbol = "DOGE/USDT"
symbol = "BTC/USDT"
symbol = "ETH/USDT"
For perpetual futures (different endpoint):
symbol = "DOGE/USDT:USDT" (note the extra :USDT suffix)
def normalize_symbol(symbol: str, market_type: str = "spot") -> str:
"""Normalize symbol format for different exchanges."""
# Remove any existing separators
symbol = symbol.replace("-", "").replace("_", "")
if market_type == "spot":
# Assume last 4 chars are quote currency (USDT, BUSD, etc.)
quote = symbol[-4:]
base = symbol[:-4]
return f"{base}/{quote}"
elif market_type == "futures":
quote = symbol[-4:]
base = symbol[:-4]
return f"{base}/{quote}:{quote}"
return symbol
Test normalization
print(normalize_symbol("DOGEUSDT")) # Output: DOGE/USDT
print(normalize_symbol("BTCUSDT", "spot")) # Output: BTC/USDT
Cause: Symbol format mismatches between what your code sends and what CoinEx expects.
Fix: Always use BASE/QUOTE format for spot markets (e.g., DOGE/USDT).
Error 4: Empty Order Book Response
# ❌ PROBLEMATIC - No null checking
bids = data['bids'] # Crashes if data is None
best_bid = bids[0][0] # IndexError if empty list
✅ ROBUST - Proper null and empty checking
def safe_get_orderbook(symbol: str, max_retries: int = 3) -> dict:
"""Fetch order book with proper error handling."""
for attempt in range(max_retries):
try:
data = get_coinex_orderbook(symbol, limit=50)
# Validate response structure
if not data:
raise ValueError(f"Empty response for {symbol}")
if 'bids' not in data or 'asks' not in data:
raise ValueError(f"Missing order book keys in response")
if len(data['bids']) == 0 or len(data['asks']) == 0:
raise ValueError(f"Empty order book for {symbol}")
# Validate data types
if not isinstance(data['bids'][0], (list, tuple)) or \
len(data['bids'][0]) < 2:
raise ValueError(f"Invalid bid format in response")
return data
except Exception as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt < max_retries - 1:
time.sleep(1)
else:
raise ValueError(f"All {max_retries} attempts failed for {symbol}")
return None
Usage with safe fetching
data = safe_get_orderbook("DOGE/USDT")
if data and len(data['bids']) > 0:
best_bid = float(data['bids'][0][0])
else:
print("Using fallback price source...")
Cause: Network issues, exchange maintenance, or invalid symbols return empty responses.
Fix: Always validate API responses before accessing nested data structures.
Advanced Topics: Scaling Your Research
Multi-Exchange Comparison
One powerful use case is comparing liquidity across exchanges to find the best execution venue:
def compare_liquidity(symbol: str, exchanges: list = None) -> pd.DataFrame:
"""
Compare order book depth across multiple exchanges.
"""
if exchanges is None:
exchanges = ['coinex', 'binance', 'bybit', 'okx']
results = []
for exchange in exchanges:
try:
data = get_orderbook_generic(symbol, exchange, limit=100)
# Calculate metrics
bid_depth = sum(float(b[0]) * float(b[1]) for b in data['bids'][:10])
ask_depth = sum(float(a[0]) * float(a[1]) for a in data['asks'][:10])
spread = float(data['asks'][0][0]) - float(data['bids'][0][0])
spread_bps = (spread / float(data['bids'][0][0])) * 10000
results.append({
'exchange': exchange,
'bid_depth_10': bid_depth,
'ask_depth_10': ask_depth,
'spread_bps': spread_bps,
'best_bid': float(data['bids'][0][0]),
'best_ask': float(data['asks'][0][0])
})
except Exception as e:
print(f"Failed to fetch {exchange}: {e