I spent three months building automated market-making infrastructure for a crypto arbitrage fund, and the biggest headache wasn't the trading logic—it was getting reliable, low-latency data from multiple exchanges simultaneously. After testing WebSocket connections directly to Binance, Bybit, OKX, and Deribit, I discovered that maintaining four separate connection streams with proper reconnection logic, message ordering, and error handling ate up 60% of my development time. That's when I integrated Tardis.dev as a unified data relay and combined it with HolySheep AI for real-time strategy analysis. The result: a 70% reduction in data infrastructure code and sub-100ms decision latency for my market-making bot.

What is Tardis.dev and Why Market Makers Need It

Tardis.dev provides consolidated market data feeds from major crypto exchanges including Binance, Bybit, OKX, and Deribit. Instead of maintaining separate WebSocket connections to each exchange with their unique API quirks, you connect once to Tardis and receive normalized data streams for all supported exchanges. This includes:

For market-makers, the killer feature is cross-exchange order book aggregation. You can detect arbitrage opportunities between exchanges in milliseconds and adjust your quotes before the spread closes.

Who This Tutorial Is For

Target Audience Analysis
Perfect fit:Quant funds building multi-exchange market-making bots, algorithmic traders needing unified data feeds, DeFi protocols requiring cross-exchange price feeds, arbitrage traders targeting Binance-OKX-Bybit triangular spreads
Overkill:Individual traders using single-exchange REST APIs, long-term position holders who don't need sub-second data, developers building non-trading applications
Prerequisites:Python/Node.js proficiency, basic WebSocket knowledge, exchange account setup, understanding of market-making concepts

The Problem: Multi-Exchange Data Fragmentation

When I started building my market-making system, I connected directly to each exchange's WebSocket API. Here's what that architecture looked like:

# The OLD approach - Direct exchange connections (DON'T DO THIS)
import asyncio
import websockets
import json

class MultiExchangeConnector:
    def __init__(self):
        self.connections = {
            'binance': 'wss://stream.binance.com:9443/ws',
            'bybit': 'wss://stream.bybit.com/v5/public/spot',
            'okx': 'wss://ws.okx.com:8443/ws/v5/public',
            'deribit': 'wss://www.deribit.com/ws/api/v2'
        }
        self.message_queues = {k: asyncio.Queue() for k in self.connections}
        self.reconnect_attempts = {k: 0 for k in self.connections}
        
    async def connect_exchange(self, exchange: str, url: str):
        """Each exchange has different message formats and reconnection logic"""
        while True:
            try:
                async with websockets.connect(url) as ws:
                    await self.subscribe(ws, exchange)
                    async for message in ws:
                        data = json.loads(message)
                        # Normalize different exchange formats manually
                        normalized = self.normalize(exchange, data)
                        await self.message_queues[exchange].put(normalized)
            except Exception as e:
                self.reconnect_attempts[exchange] += 1
                wait = min(30, 2 ** self.reconnect_attempts[exchange])
                print(f"{exchange} disconnected, retrying in {wait}s")
                await asyncio.sleep(wait)
    
    def normalize(self, exchange, data):
        """40+ lines of format-specific parsing per exchange"""
        # Binance: {"e": "trade", "s": "BTCUSDT", "p": "50000.00", "q": "0.1"}
        # Bybit: {"topic": "trades", "data": [{"s": "BTCUSDT", "p": "50000", "v": "0.1"}]}
        # OKX: {"arg": {"channel": "trades"}, "data": [...]}
        # Deribit: {"params": {"data": [{"price": 50000, "quantity": 0.1}]}
        # YOU HAVE TO WRITE PARSING LOGIC FOR EACH
        pass

This approach creates maintenance nightmares. Each exchange updates their API format, requires different authentication flows, and has unique rate limits. I spent more time debugging connection issues than improving my trading strategy.

The Solution: Tardis.dev Unified Relay

Tardis.dev solves this by providing a single WebSocket connection that handles all exchanges. The normalized message format works across Binance, Bybit, OKX, and Deribit:

# The NEW approach - Tardis unified relay
import asyncio
import json
from tardis_client import TardisClient

class TardisMarketMaker:
    def __init__(self, api_key: str, holy_sheep_client):
        self.tardis = TardisClient(api_key=api_key)
        self.llm = holy_sheep_client  # HolySheep AI for strategy analysis
        self.orderbooks = {}  # Unified order book storage
        
    async def start_market_data_stream(self, exchange: str, symbol: str):
        """Single connection, unified format, all exchanges"""
        # Tardis messages are normalized - same structure regardless of source
        async for message in self.tardis.subscribe(
            exchange=exchange,
            channel='orderbook-L1',  # Level 1 book (best bid/ask)
            symbols=[symbol]
        ):
            await self.process_orderbook_update(exchange, symbol, message)
            
    async def start_trade_stream(self, exchanges: list, symbols: list):
        """Subscribe to multiple exchanges simultaneously"""
        # One subscription, all exchanges, unified format
        subscriptions = [
            (exchange, 'trade', [symbol]) 
            for exchange in exchanges 
            for symbol in symbols
        ]
        
        async for message in self.tardis.subscribe_all(subscriptions):
            # Unified message format from ALL exchanges
            await self.process_trade(message)
            
    async def process_orderbook_update(self, exchange: str, symbol: str, data: dict):
        """Process order book updates - same format from any exchange"""
        key = f"{exchange}:{symbol}"
        
        if data['type'] == 'snapshot':
            self.orderbooks[key] = {
                'bids': {p: float(v) for p, v in data['bids']},
                'asks': {p: float(v) for p, v in data['asks']}
            }
        elif data['type'] == 'delta':
            # Apply incremental updates
            for price, volume in data['bids']:
                if float(volume) == 0:
                    self.orderbooks[key]['bids'].pop(price, None)
                else:
                    self.orderbooks[key]['bids'][price] = float(volume)
            for price, volume in data['asks']:
                if float(volume) == 0:
                    self.orderbooks[key]['asks'].pop(price, None)
                else:
                    self.orderbooks[key]['asks'][price] = float(volume)
        
        # Trigger strategy analysis with HolySheep AI
        await self.analyze_spread_opportunity(key)
        
    async def analyze_spread_opportunity(self, book_key: str):
        """Use HolySheep AI to analyze cross-exchange arbitrage"""
        book = self.orderbooks.get(book_key)
        if not book or not book['bids'] or not book['asks']:
            return
            
        best_bid = max(float(p) for p in book['bids'].keys())
        best_ask = min(float(p) for p in book['asks'].keys())
        spread_bps = ((best_ask - best_bid) / best_bid) * 10000
        
        # Only analyze large spreads
        if spread_bps < 2:  # Less than 2 basis points
            return
            
        # Get cross-exchange data for arbitrage detection
        cross_data = self.get_cross_exchange_prices(book_key)
        
        if cross_data:
            prompt = f"""Analyze this market data for arbitrage:
            Current book: Best bid {best_bid}, Best ask {best_ask}, Spread {spread_bps:.1f} bps
            Cross-exchange prices: {cross_data}
            
            Should I execute a market-making quote? Consider:
            1. Inventory risk (current positions)
            2. Funding rate differential
            3. Liquidity conditions
            4. Recent price momentum
            
            Respond with: EXECUTE or WAIT and the reasoning."""
            
            response = await self.llm.chat.completions.create(
                model="gpt-4.1",
                messages=[{"role": "user", "content": prompt}],
                temperature=0.1,
                max_tokens=150
            )
            
            decision = response.choices[0].message.content
            if decision.startswith("EXECUTE"):
                await self.execute_market_making_quote(book_key, best_bid, best_ask)

Complete HolySheep Integration for Strategy Analysis

Here's the production-ready integration with HolySheep AI's unified API featuring $1=¥1 pricing (85%+ savings vs. ¥7.3 market rates) and sub-50ms latency:

import asyncio
import aiohttp
from typing import List, Dict, Optional
from dataclasses import dataclass
from datetime import datetime
import json

@dataclass
class StrategyDecision:
    action: str  # "quote_bid", "quote_ask", "spread_widen", "hold"
    price: float
    size: float
    confidence: float
    reasoning: str
    timestamp: datetime

class HolySheepTardisMarketMaker:
    """
    Production market-making bot using Tardis.dev data 
    and HolySheep AI for strategy decisions.
    """
    
    BASE_URL = "https://api.holysheep.ai/v1"
    
    def __init__(self, api_key: str, tardis_key: str):
        self.holy_sheep_key = api_key
        self.tardis_client = None  # Initialize Tardis client
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        # Price tracking for all subscribed instruments
        self.price_history: Dict[str, List[dict]] = {}
        self.positions: Dict[str, float] = {}
        
    async def analyze_market_conditions(
        self, 
        exchange: str, 
        symbol: str, 
        trades: List[dict],
        orderbook: dict
    ) -> StrategyDecision:
        """Use HolySheep AI to analyze market and generate quote strategy"""
        
        # Calculate market metrics
        recent_trades = trades[-20:] if len(trades) >= 20 else trades
        buy_volume = sum(float(t['quantity']) for t in recent_trades if t['side'] == 'buy')
        sell_volume = sum(float(t['quantity']) for t in recent_trades if t['side'] == 'sell')
        volume_imbalance = (buy_volume - sell_volume) / (buy_volume + sell_volume + 1e-10)
        
        # Calculate order book pressure
        bid_depth = sum(float(v) for v in orderbook.get('bids', {}).values())
        ask_depth = sum(float(v) for v in orderbook.get('asks', {}).values())
        book_pressure = (bid_depth - ask_depth) / (bid_depth + ask_depth + 1e-10)
        
        # Mid price and spread
        bids = orderbook.get('bids', {})
        asks = orderbook.get('asks', {})
        if not bids or not asks:
            return StrategyDecision("hold", 0, 0, 0, "No liquidity", datetime.now())
            
        best_bid = max(float(p) for p in bids.keys())
        best_ask = min(float(p) for p in asks.keys())
        mid_price = (best_bid + best_ask) / 2
        spread_bps = ((best_ask - best_bid) / mid_price) * 10000
        
        # Build analysis prompt with current market state
        market_analysis_prompt = f"""You are a market-making AI analyzing {exchange}:{symbol}.

Current Market State:
- Best Bid: {best_bid} | Best Ask: {best_ask}
- Spread: {spread_bps:.2f} bps
- Mid Price: {mid_price}
- Volume (last 20 trades): Buy={buy_volume:.4f}, Sell={sell_volume:.4f}
- Volume Imbalance: {volume_imbalance:.3f} (positive=buy pressure)
- Book Pressure: {book_pressure:.3f} (positive=bid depth stronger)

Inventory: {self.positions.get(symbol, 0)}
Exchange: {exchange}

As a market maker, decide your next action:
1. "quote_bid" - Place bid (buy) quote
2. "quote_ask" - Place ask (sell) quote  
3. "spread_widen" - Widen your spread by quoting further from mid
4. "hold" - Don't quote, await better conditions

Provide your decision with:
- Action
- Suggested quote price (as distance from mid in bps, or absolute price)
- Quote size (as fraction of average trade size, 0.0-1.0)
- Confidence (0.0-1.0)
- Brief reasoning (max 50 words)

Respond in JSON: {{"action": "...", "price_bps": ..., "size": ..., "confidence": ..., "reasoning": "..."}}"""
        
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.BASE_URL}/chat/completions",
                headers=self.headers,
                json={
                    "model": "deepseek-v3.2",  # $0.42/1M tokens - best for high-frequency analysis
                    "messages": [{"role": "user", "content": market_analysis_prompt}],
                    "temperature": 0.1,
                    "max_tokens": 200,
                    "response_format": {"type": "json_object"}
                },
                timeout=aiohttp.ClientTimeout(total=0.05)  # 50ms timeout for sub-50ms target
            ) as response:
                if response.status == 200:
                    result = await response.json()
                    content = result['choices'][0]['message']['content']
                    decision = json.loads(content)
                    
                    # Convert bps to actual price
                    if 'bps' in str(decision.get('price_bps', '')):
                        offset = decision['price_bps'] / 10000 * mid_price
                    else:
                        offset = float(decision.get('price_bps', 0)) / 10000 * mid_price
                    
                    quote_price = mid_price - offset if 'bid' in decision['action'] else mid_price + offset
                    
                    return StrategyDecision(
                        action=decision['action'],
                        price=quote_price,
                        size=float(decision.get('size', 0)) * 0.1,  # Scale down for safety
                        confidence=float(decision.get('confidence', 0)),
                        reasoning=decision.get('reasoning', ''),
                        timestamp=datetime.now()
                    )
                else:
                    # Fallback to simple spread-widening on API failure
                    return StrategyDecision(
                        "spread_widen", mid_price, 0, 0.5, 
                        "API timeout, using safety mode", datetime.now()
                    )
    
    async def run_backtest_analysis(
        self, 
        historical_data: List[dict]
    ) -> dict:
        """Analyze historical data using HolySheep to tune strategy parameters"""
        
        # Format historical trades for analysis
        formatted_trades = []
        for trade in historical_data[-100:]:
            formatted_trades.append({
                'price': trade['price'],
                'quantity': trade['quantity'],
                'side': trade['side'],
                'timestamp': trade['timestamp']
            })
        
        prompt = f"""Analyze this {len(formatted_trades)}-trade historical sample for market-making optimization.

Trades: {json.dumps(formatted_trades)}

Provide:
1. Optimal spread width (in bps) for this asset's typical spread
2. Ideal quote size relative to average trade
3. Adverse selection risk (how often do you get filled when price moves against you?)
4. Recommendations for any unusual patterns

Respond in JSON with specific numbers."""
        
        async with aiohttp.ClientSession() as session:
            async with session.post(
                f"{self.BASE_URL}/chat/completions",
                headers=self.headers,
                json={
                    "model": "claude-sonnet-4.5",  # $15/1M tokens - use for complex analysis
                    "messages": [{"role": "user", "content": prompt}],
                    "temperature": 0.2,
                    "max_tokens": 500
                }
            ) as response:
                result = await response.json()
                return json.loads(result['choices'][0]['message']['content'])

Example usage

async def main(): # Initialize with your HolySheep API key # Sign up at https://www.holysheep.ai/register market_maker = HolySheepTardisMarketMaker( api_key="YOUR_HOLYSHEEP_API_KEY", tardis_key="YOUR_TARDIS_KEY" ) # Analyze market conditions decision = await market_maker.analyze_market_conditions( exchange='binance', symbol='BTC-USDT', trades=[ {'price': 67450.00, 'quantity': 0.5, 'side': 'buy'}, {'price': 67451.00, 'quantity': 0.3, 'side': 'sell'}, # ... more trades from Tardis stream ], orderbook={ 'bids': {'67449.00': 5.2, '67448.00': 3.1}, 'asks': {'67452.00': 4.8, '67453.00': 6.2} } ) print(f"Strategy Decision: {decision.action}") print(f"Quote Price: ${decision.price:,.2f}") print(f"Confidence: {decision.confidence:.1%}") if __name__ == "__main__": asyncio.run(main())

Configuration for Multi-Exchange Aggregation

Here's the complete configuration for subscribing to multiple exchanges simultaneously through Tardis.dev:

# tardis_config.py
import asyncio
from tardis_client import TardisClient, MessageType

Tardis.dev subscription configuration

TARDIS_SUBSCRIPTIONS = { # Perpetual futures (high volume, good for market-making) 'perpetuals': [ {'exchange': 'binance', 'channel': 'trade', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'binance', 'channel': 'orderbook-L2', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'bybit', 'channel': 'trade', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'bybit', 'channel': 'orderbook-L2', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'okx', 'channel': 'trade', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'okx', 'channel': 'orderbook-L2', 'symbol': 'BTC-PERPETUAL'}, ], # Spot markets (tight spreads, high-frequency) 'spot': [ {'exchange': 'binance', 'channel': 'trade', 'symbol': 'BTC-USDT'}, {'exchange': 'binance', 'channel': 'orderbook-L2', 'symbol': 'BTC-USDT'}, {'exchange': 'okx', 'channel': 'trade', 'symbol': 'BTC-USDT'}, {'exchange': 'okx', 'channel': 'orderbook-L2', 'symbol': 'BTC-USDT'}, ], # Funding rate monitoring (for carry strategies) 'funding': [ {'exchange': 'binance', 'channel': 'funding', 'symbol': 'BTC-PERPETUAL'}, {'exchange': 'bybit', 'channel': 'funding', 'symbol': 'BTC-PERPETUAL'}, ] }

Market-making parameters

MARKET_MAKING_CONFIG = { 'max_position_size': 2.0, # BTC 'max_spread_widening': 10.0, # bps from fair value 'min_confidence_threshold': 0.6, 'quote_size_base': 0.1, # BTC 'cancel_threshold_seconds': 5.0, # HolySheep AI model selection by task type 'models': { 'realtime_quote': 'deepseek-v3.2', # $0.42/1M tokens - fast decisions 'strategy_analysis': 'gemini-2.5-flash', # $2.50/1M tokens - balanced 'backtest_review': 'claude-sonnet-4.5', # $15/1M tokens - deep analysis } } async def process_tardis_messages(): """Main message processing loop""" client = TardisClient(api_key="YOUR_TARDIS_API_KEY") # Flatten all subscriptions all_subscriptions = [ (s['exchange'], s['channel'], [s['symbol']]) for s in TARDIS_SUBSCRIPTIONS['perpetuals'] + TARDIS_SUBSCRIPTIONS['spot'] ] # Unified message handler - same code for all exchanges! async for message in client.subscribe_all(all_subscriptions): if message.type == MessageType.TRADE: # Unified trade format: message.timestamp, message.price, message.quantity, message.side print(f"Trade {message.exchange}:{message.symbol} | {message.side} {message.quantity} @ {message.price}") elif message.type == MessageType.ORDERBOOK_SNAPSHOT: print(f"Orderbook snapshot {message.exchange}:{message.symbol} | {len(message.bids)} bids, {len(message.asks)} asks") elif message.type == MessageType.ORDERBOOK_DELTA: # Incremental update - apply to local order book print(f"Orderbook delta {message.exchange}:{message.symbol} | {len(message.bids)} bid updates, {len(message.asks)} ask updates") if __name__ == "__main__": asyncio.run(process_tardis_messages())

Pricing and ROI Analysis

HolySheep AI vs. Competition (2026 Pricing)
ProviderRate1M Token CostAnnual Cost (1M req/day)
HolySheep AI¥1 = $1$0.42 (DeepSeek V3.2)$153,300
Chinese Market Rate¥7.3 per $1$3.07$1,120,550
OpenAI GPT-4.1Standard USD$8.00$2,920,000
Anthropic Claude Sonnet 4.5Standard USD$15.00$5,475,000
Google Gemini 2.5 FlashStandard USD$2.50$912,500

ROI Calculation for Market-Making Bot:

Why Choose HolySheep for Trading Infrastructure

Common Errors and Fixes

Error 1: Tardis Connection Timeout During High Volatility

Symptom: "Connection timeout" errors when subscribing to multiple high-frequency streams during market events. Your market-making bot misses critical arbitrage opportunities.

# PROBLEM: Default timeout too short for burst traffic
async for message in self.tardis.subscribe(exchange='binance', channel='trade', symbols=['BTC-PERPETUAL']):
    # Default timeout may cause drops during high volatility

SOLUTION: Implement message buffering and exponential backoff

class RobustTardisConnector: def __init__(self, api_key: str): self.client = TardisClient(api_key=api_key) self.message_buffer = asyncio.Queue(maxsize=10000) self.reconnect_delay = 1.0 async def subscribe_with_retry(self, exchange: str, channel: str, symbols: List[str]): while True: try: async for message in self.client.subscribe(exchange, channel, symbols): try: self.message_buffer.put_nowait(message) except asyncio.QueueFull: # Buffer full - keep latest messages, drop oldest try: self.message_buffer.get_nowait() self.message_buffer.put_nowait(message) except: pass self.reconnect_delay = 1.0 # Reset on success except Exception as e: print(f"Tardis connection error: {e}, retrying in {self.reconnect_delay}s") await asyncio.sleep(self.reconnect_delay) self.reconnect_delay = min(60, self.reconnect_delay * 2) # Max 60s backoff

Error 2: HolySheep API Returns 429 Too Many Requests

Symptom: "Rate limit exceeded" errors when running high-frequency market analysis. Your quote generation stalls during critical trading windows.

# PROBLEM: No rate limiting on API calls

SOLUTION: Implement request throttling with model-specific limits

import time from collections import defaultdict class HolySheepRateLimiter: def __init__(self, requests_per_minute: int = 60): self.rpm_limit = requests_per_minute self.requests = defaultdict(list) async def throttled_request(self, session, url: str, headers: dict, payload: dict): now = time.time() # Clean old requests (older than 60 seconds) self.requests[url] = [t for t in self.requests[url] if now - t < 60] if len(self.requests[url]) >= self.rpm_limit: # Wait until oldest request expires sleep_time = 60 - (now - self.requests[url][0]) if sleep_time > 0: await asyncio.sleep(sleep_time) self.requests[url] = self.requests[url][1:] self.requests[url].append(time.time()) async with session.post(url, headers=headers, json=payload) as resp: if resp.status == 429: # Explicit rate limit - respect Retry-After header retry_after = int(resp.headers.get('Retry-After', 5)) await asyncio.sleep(retry_after) return await self.throttled_request(session, url, headers, payload) return resp

Usage in market maker

limiter = HolySheepRateLimiter(requests_per_minute=100) # Conservative limit

Error 3: Order Book State Desynchronization

Symptom: Local order book state doesn't match exchange state. Quotes are placed at stale prices, causing adverse fills.

# PROBLEM: Delta updates applied without verification

SOLUTION: Implement sequence checking and full resync

class OrderBookManager: def __init__(self): self.books = {} self.sequence_numbers = {} # Track message sequence per exchange def apply_update(self, exchange: str, symbol: str, message: dict): key = f"{exchange}:{symbol}" # Check if we need a snapshot resync if key not in self.books: if message['type'] != 'snapshot': # We're out of sync - need to fetch snapshot return None # Signal caller to request snapshot self.books[key] = { 'bids': {}, 'asks': {} } # Verify sequence number (if provided by exchange) seq = message.get('sequence') if seq and key in self.sequence_numbers: expected = self.sequence_numbers[key] + 1 if seq != expected: print(f"Sequence gap detected: expected {expected}, got {seq}") self.books[key] = None # Invalidate - need resync return None self.sequence_numbers[key] = seq or (self.sequence_numbers.get(key, 0) + 1) if message['type'] == 'snapshot': self.books[key] = { 'bids': {float(p): float(v) for p, v in message['bids']}, 'asks': {float(p): float(v) for p, v in message['asks']} } elif message['type'] == 'delta': book = self.books[key] for price, volume in message.get('bids', []): p, v = float(price), float(volume) if v == 0: book['bids'].pop(p, None) else: book['bids'][p] = v for price, volume in message.get('asks', []): p, v = float(price), float(volume) if v == 0: book['asks'].pop(p, None) else: book['asks'][p] = v return True

Error 4: Cross-Exchange Arbitrage Detection Latency

Symptom: Detecting arbitrage opportunities but quotes execute too slowly. By the time your bot quotes on Exchange A, the spread has closed.

# PROBLEM: Sequential processing causes latency

SOLUTION: Parallel processing with pre-computed arbitrage signals

class ArbitrageDetector: def __init__(self): self.latest_prices = {} # Cache latest prices per exchange self.price_timestamps = {} def update_price(self, exchange: str, symbol: str, price: float, timestamp: float): key = f"{exchange}:{symbol}" self.latest_prices[key] = price self.price_timestamps[key] = timestamp def detect_arbitrage(self, symbols: List[str], exchanges: List[str]) -> List[dict]: """Pre-compute all possible arbitrage pairs in O(n²) check""" opportunities = [] for symbol in symbols: # Get best bid/ask across all exchanges symbol_prices = { ex: self.latest_prices.get(f"{ex}:{symbol}") for ex in exchanges } # Find cross-exchange spreads for buy_ex in exchanges: for sell_ex in exchanges: if buy_ex == sell_ex: continue buy_price = symbol_prices.get(buy_ex) sell_price = symbol_prices.get(sell_ex) if buy_price and sell_price: spread = ((sell_price - buy_price) / buy_price) * 100 # percent latency = max( self.price_timestamps.get(f"{buy_ex}:{symbol}", 0), self.price_timestamps.get(f"{sell_ex}:{symbol}", 0) ) if spread > 0.05 and latency > 0: # >0.05% spread opportunities.append({ 'buy_exchange': buy_ex, 'sell_exchange': sell_ex, 'symbol': symbol, 'buy_price': buy_price, 'sell_price': sell_price, 'spread_pct': spread, 'data_age_ms': (time.time() - latency) * 1000 }) return sorted(opportunities, key=lambda x: -x['spread_pct