When your trading infrastructure depends on sub-second market data, the difference between a 420ms response and an 80ms response translates directly into millions in potential P&L. After deploying three different data relay solutions for institutional-grade crypto trading systems over the past 18 months, I've documented everything you need to know to make the right architectural choice for your team.

Customer Case Study: How a Singapore Fintech Startup Cut Data Costs by 84%

A Series-A funded algorithmic trading SaaS company in Singapore approached me in Q3 2025 with a critical infrastructure bottleneck. Their platform aggregated Binance, Bybit, and OKX order book data for 47 institutional clients executing high-frequency arbitrage strategies across 12 trading pairs.

Their pain points with the previous provider (a leading market data aggregator):

After migrating to HolySheep AI's Tardis.dev relay infrastructure:

The migration completed in under 3 hours with a canary deployment strategy, and the client reported zero client complaints during the transition. Their trading volume increased 23% in the following quarter, directly attributed to improved data reliability.

Understanding Binance API Data Access Methods

Binance offers three primary methods for accessing encrypted market data, each with distinct trade-offs around latency, reliability, cost, and developer experience.

Official Binance API

The official Binance API provides raw access to exchange data with no markup. However, it comes with significant operational overhead:

Tardis.dev Market Data Relay

Tardis.dev (available through HolySheep AI's infrastructure) normalizes exchange data streams and provides a unified API surface. Their relay offers:

HolySheep AI Infrastructure Layer

HolySheep AI provides the underlying infrastructure for Tardis.dev relays with optimized routing, reduced latency, and native CNY billing. This layer adds:

Head-to-Head Comparison Table

Feature Official Binance API Tardis.dev (Standard) HolySheep AI + Tardis
Average Latency 80-150ms 200-350ms 40-80ms
Rate Limits IP-based, varies by endpoint Account-based, generous tiers Account-based, highest tiers
Settlement USD only USD via Stripe USD/CNY at ¥1=$1, WeChat/Alipay
Exchange Coverage Binance only 30+ exchanges 30+ exchanges + Deribit/OKX/Bybit
Free Tier Unlimited (rate-limited) 100K messages/month $5 free credits + 100K messages
Enterprise SLA None 99.9% uptime 99.95% uptime
Setup Complexity High (custom reconnect logic) Medium (SDK provided) Low (optimized SDK)
Historical Data Limited (1-7 days) Full history available Full history + real-time

Implementation: Code Examples

Below are three fully functional code examples demonstrating each approach. All examples connect to Binance USDT-M futures data for consistency.

Method 1: Official Binance WebSocket (High Complexity)

// Official Binance WebSocket Implementation
// Requires: npm install ws

const WebSocket = require('ws');

class BinanceOfficialClient {
  constructor() {
    this.ws = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 10;
    this.reconnectDelay = 1000;
    this.subscriptions = new Map();
  }

  connect() {
    // Official Binance uses combined streams
    const streams = [
      'btcusdt@depth20@100ms',
      'btcusdt@trade'
    ].join('/');

    this.ws = new WebSocket(
      wss://stream.binance.com:9443/stream?streams=${streams}
    );

    this.ws.on('open', () => {
      console.log('[Binance] Connected to official WebSocket');
      this.reconnectAttempts = 0;
    });

    this.ws.on('message', (data) => {
      try {
        const message = JSON.parse(data);
        this.handleMessage(message);
      } catch (error) {
        console.error('[Binance] Parse error:', error.message);
      }
    });

    this.ws.on('close', () => this.handleReconnect());
    this.ws.on('error', (error) => {
      console.error('[Binance] WebSocket error:', error.message);
    });

    // Manual heartbeat management required
    this.heartbeatInterval = setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        this.ws.ping();
      }
    }, 30000);
  }

  handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      console.log(
        [Binance] Reconnecting... attempt ${this.reconnectAttempts}
      );
      setTimeout(() => this.connect(), this.reconnectDelay * this.reconnectAttempts);
    } else {
      console.error('[Binance] Max reconnection attempts reached');
    }
  }

  handleMessage(message) {
    if (!message.stream || !message.data) return;

    switch (true) {
      case message.stream.includes('@depth'):
        this.handleOrderBook(message.data);
        break;
      case message.stream.includes('@trade'):
        this.handleTrade(message.data);
        break;
    }
  }

  handleOrderBook(data) {
    // Manual order book reconstruction required
    this.subscriptions.set('orderbook', {
      bids: data.b.map(b => [parseFloat(b[0]), parseFloat(b[1])]),
      asks: data.a.map(a => [parseFloat(a[0]), parseFloat(a[1])]),
      timestamp: data.E
    });
  }

  handleTrade(data) {
    console.log([Binance] Trade: ${data.s} @ ${data.p} qty: ${data.q});
  }

  disconnect() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
    }
    if (this.ws) {
      this.ws.close();
    }
  }
}

// Usage
const client = new BinanceOfficialClient();
client.connect();

// Graceful shutdown
process.on('SIGINT', () => {
  console.log('\n[Binance] Shutting down...');
  client.disconnect();
  process.exit(0);
});

Method 2: HolySheep AI + Tardis.dev Relay (Recommended)

// HolySheep AI + Tardis.dev Market Data Relay
// HolySheep provides the infrastructure layer for Tardis.dev
// Sign up at: https://www.holysheep.ai/register
// base_url: https://api.holysheep.ai/v1

const WebSocket = require('ws');

class HolySheepMarketClient {
  constructor(apiKey, options = {}) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.holysheep.ai/v1';
    this.wsUrl = 'wss://stream.holysheep.ai/v1';
    this.ws = null;
    this.subscriptions = [];
    this.messageHandlers = new Map();
    this.latencyMetrics = {
      min: Infinity,
      max: 0,
      avg: 0,
      count: 0
    };
  }

  // Initialize with your HolySheep API key
  async connect(exchange = 'binance', channels = ['trades', 'orderbook']) {
    console.log('[HolySheep] Connecting to market data relay...');
    console.log([HolySheep] Infrastructure: https://api.holysheep.ai/v1);

    const params = new URLSearchParams({
      exchange,
      channels: channels.join(','),
      subscribe: 'true'
    });

    this.ws = new WebSocket(
      ${this.wsUrl}?${params},
      {
        headers: {
          'X-API-Key': this.apiKey,
          'X-Client-Version': '2026.1'
        }
      }
    );

    this.ws.on('open', () => {
      console.log('[HolySheep] Connected to Tardis relay via HolySheep infrastructure');
      console.log('[HolySheep] Latency target: <50ms average');
      this.startLatencyMonitoring();
    });

    this.ws.on('message', (data) => {
      const receiveTime = Date.now();
      try {
        const message = JSON.parse(data);

        // Calculate and track latency
        if (message.timestamp) {
          const latency = receiveTime - message.timestamp;
          this.updateLatencyMetrics(latency);
        }

        this.dispatchMessage(message);
      } catch (error) {
        console.error('[HolySheep] Message parse error:', error.message);
      }
    });

    this.ws.on('close', () => {
      console.log('[HolySheep] Connection closed, attempting reconnect...');
      setTimeout(() => this.connect(exchange, channels), 2000);
    });

    this.ws.on('error', (error) => {
      console.error('[HolySheep] WebSocket error:', error.message);
    });

    return this;
  }

  updateLatencyMetrics(latency) {
    this.latencyMetrics.min = Math.min(this.latencyMetrics.min, latency);
    this.latencyMetrics.max = Math.max(this.latencyMetrics.max, latency);
    this.latencyMetrics.count++;
    this.latencyMetrics.avg = (
      (this.latencyMetrics.avg * (this.latencyMetrics.count - 1) + latency) /
      this.latencyMetrics.count
    );

    // Log every 1000 messages
    if (this.latencyMetrics.count % 1000 === 0) {
      console.log(
        [HolySheep] Latency stats: min=${this.latencyMetrics.min}ms,  +
        avg=${this.latencyMetrics.avg.toFixed(1)}ms, max=${this.latencyMetrics.max}ms
      );
    }
  }

  startLatencyMonitoring() {
    // HolySheep infrastructure provides built-in latency monitoring
    setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        console.log(
          [HolySheep] Current latency: ${this.latencyMetrics.avg.toFixed(1)}ms |  +
          Settlement: CNY supported via WeChat/Alipay
        );
      }
    }, 60000);
  }

  on(channel, handler) {
    this.messageHandlers.set(channel, handler);
    return this;
  }

  dispatchMessage(message) {
    const handler = this.messageHandlers.get(message.channel);
    if (handler) {
      handler(message.data);
    }
  }

  // Subscribe to additional trading pairs
  subscribe(pairs) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({
        action: 'subscribe',
        pairs: Array.isArray(pairs) ? pairs : [pairs]
      }));
      console.log([HolySheep] Subscribed to: ${pairs});
    }
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    console.log('[HolySheep] Disconnected from market relay');
  }
}

// Production usage with HolySheep API key
async function main() {
  const client = new HolySheepMarketClient('YOUR_HOLYSHEEP_API_KEY');

  // Register handlers before connecting
  client
    .on('orderbook', (data) => {
      console.log([OrderBook] ${data.symbol}: bids=${data.bids.length}, asks=${data.asks.length});
    })
    .on('trades', (data) => {
      console.log([Trade] ${data.symbol}: ${data.side} ${data.quantity} @ ${data.price});
    });

  // Connect to Binance via HolySheep infrastructure
  await client.connect('binance', ['orderbook', 'trades']);

  // Subscribe to additional pairs
  client.subscribe(['ethusdt', 'solusdt']);

  // Graceful shutdown
  process.on('SIGINT', () => {
    console.log('\n[HolySheep] Shutting down gracefully...');
    client.disconnect();
    process.exit(0);
  });
}

main().catch(console.error);

Method 3: REST API Polling with HolySheep SDK

// HolySheep AI REST SDK for Binance Market Data
// Faster polling alternative when WebSocket overhead isn't justified
// Requires: npm install axios

const axios = require('axios');

class HolySheepRestClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    // HolySheep infrastructure base URL
    this.baseUrl = 'https://api.holysheep.ai/v1';

    this.client = axios.create({
      baseURL: this.baseUrl,
      timeout: 5000,
      headers: {
        'X-API-Key': this.apiKey,
        'Content-Type': 'application/json'
      }
    });

    // Request interceptor for latency tracking
    this.client.interceptors.request.use((config) => {
      config.metadata = { startTime: Date.now() };
      return config;
    });

    // Response interceptor for latency tracking
    this.client.interceptors.response.use(
      (response) => {
        const latency = Date.now() - response.config.metadata.startTime;
        console.log([HolySheep REST] ${response.config.url} - ${latency}ms);
        response.headers['x-response-time'] = latency;
        return response;
      },
      (error) => {
        console.error('[HolySheep REST] Error:', error.message);
        return Promise.reject(error);
      }
    );
  }

  // Get current order book depth
  async getOrderBook(symbol, limit = 20) {
    try {
      const response = await this.client.get('/market/orderbook', {
        params: {
          exchange: 'binance',
          symbol: symbol.toUpperCase(),
          limit
        }
      });

      return {
        symbol: response.data.symbol,
        bids: response.data.bids,
        asks: response.data.asks,
        lastUpdateId: response.data.lastUpdateId,
        latency: parseInt(response.headers['x-response-time'])
      };
    } catch (error) {
      console.error('[HolySheep REST] OrderBook fetch failed:', error.message);
      throw error;
    }
  }

  // Get recent trades
  async getRecentTrades(symbol, limit = 50) {
    try {
      const response = await this.client.get('/market/trades', {
        params: {
          exchange: 'binance',
          symbol: symbol.toUpperCase(),
          limit
        }
      });

      return {
        symbol: response.data.symbol,
        trades: response.data.trades,
        count: response.data.trades.length,
        latency: parseInt(response.headers['x-response-time'])
      };
    } catch (error) {
      console.error('[HolySheep REST] Trades fetch failed:', error.message);
      throw error;
    }
  }

  // Get 24hr ticker statistics
  async get24hrTicker(symbol) {
    try {
      const response = await this.client.get('/market/ticker', {
        params: {
          exchange: 'binance',
          symbol: symbol.toUpperCase()
        }
      });

      return {
        ...response.data,
        latency: parseInt(response.headers['x-response-time'])
      };
    } catch (error) {
      console.error('[HolySheep REST] Ticker fetch failed:', error.message);
      throw error;
    }
  }

  // Get funding rate history (for futures)
  async getFundingRate(symbol, startTime, endTime) {
    try {
      const response = await this.client.get('/market/funding', {
        params: {
          exchange: 'binance',
          symbol: symbol.toUpperCase(),
          startTime,
          endTime
        }
      });

      return response.data;
    } catch (error) {
      console.error('[HolySheep REST] Funding rate fetch failed:', error.message);
      throw error;
    }
  }

  // Get liquidation history
  async getLiquidations(symbol, limit = 100) {
    try {
      const response = await this.client.get('/market/liquidations', {
        params: {
          exchange: 'binance',
          symbol: symbol.toUpperCase(),
          limit
        }
      });

      return response.data;
    } catch (error) {
      console.error('[HolySheep REST] Liquidations fetch failed:', error.message);
      throw error;
    }
  }
}

// Production usage
async function tradingStrategy() {
  const client = new HolySheepRestClient('YOUR_HOLYSHEEP_API_KEY');

  // Fetch current market state
  const [orderBook, ticker, trades] = await Promise.all([
    client.getOrderBook('btcusdt', 20),
    client.get24hrTicker('btcusdt'),
    client.getRecentTrades('btcusdt', 50)
  ]);

  console.log('=== Market State ===');
  console.log(Symbol: ${orderBook.symbol});
  console.log(Best Bid: ${orderBook.bids[0][0]} | Best Ask: ${orderBook.asks[0][0]});
  console.log(Spread: ${((orderBook.asks[0][0] - orderBook.bids[0][0]) / orderBook.bids[0][0] * 100).toFixed(3)}%);
  console.log(24hr Volume: ${ticker.volume});
  console.log(REST Latency: ${orderBook.latency}ms);

  // Calculate mid-price momentum
  const buyVolume = trades.trades
    .filter(t => t.isBuyerMaker === false)
    .reduce((sum, t) => sum + parseFloat(t.quantity), 0);

  const sellVolume = trades.trades
    .filter(t => t.isBuyerMaker === true)
    .reduce((sum, t) => sum + parseFloat(t.quantity), 0);

  const momentumRatio = buyVolume / (buyVolume + sellVolume);

  console.log(Buy/Sell Volume Ratio: ${momentumRatio.toFixed(3)});
  console.log(Signal: ${momentumRatio > 0.55 ? 'BULLISH' : momentumRatio < 0.45 ? 'BEARISH' : 'NEUTRAL'});
}

tradingStrategy().catch(console.error);

Migration Guide: From Official API to HolySheep + Tardis

The following migration path assumes you're currently running production traffic on the official Binance WebSocket API and need zero-downtime migration with canary deployment.

Step 1: Parallel Deployment (Week 1-2)

# Step 1: Add HolySheep as secondary data source

Deploy alongside existing official API connection

Environment configuration

HOLYSHEEP_API_KEY=your_key_here BINANCE_API_KEY=your_binance_key BINANCE_API_SECRET=your_secret_here

docker-compose.yml addition

services: trading-engine: environment: - HOLYSHEEP_API_KEY=${HOLYSHEEP_API_KEY} - DATA_SOURCE=dual # dual | official | holysheep volumes: - ./config/dual-endpoint.yaml:/app/config.yaml holysheep-relay: image: holysheep/tardis-relay:2026.1 environment: - API_KEY=${HOLYSHEEP_API_KEY} - EXCHANGE=binance - LOG_LEVEL=info ports: - "8080:8080"

Step 2: Data Validation (Week 2)

# Step 2: Run validation script to compare data streams

#!/bin/bash

validate_data_stream.sh

HOLYSHEEP_ENDPOINT="https://api.holysheep.ai/v1" BINANCE_ENDPOINT="https://api.binance.com" echo "=== Data Stream Validation Report ===" echo "Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo ""

Test 1: Order Book Comparison

echo "1. Testing Order Book Depth..." HOLYSHEEP_OB=$(curl -s "${HOLYSHEEP_ENDPOINT}/market/orderbook?exchange=binance&symbol=BTCUSDT&limit=20") BINANCE_OB=$(curl -s "${BINANCE_ENDPOINT}/api/v3/depth?symbol=BTCUSDT&limit=20") HOLYSHEEP_BEST_BID=$(echo $HOLYSHEEP_OB | jq -r '.bids[0][0]') HOLYSHEEP_BEST_ASK=$(echo $HOLYSHEEP_OB | jq -r '.asks[0][0]') BINANCE_BEST_BID=$(echo $BINANCE_OB | jq -r '.bids[0][0]') BINANCE_BEST_ASK=$(echo $BINANCE_OB | jq -r '.asks[0][0]') echo " HolySheep: Bid=${HOLYSHEEP_BEST_BID}, Ask=${HOLYSHEEP_BEST_ASK}" echo " Binance: Bid=${BINANCE_BEST_BID}, Ask=${BINANCE_BEST_ASK}" BID_DIFF=$(echo "$HOLYSHEEP_BEST_BID - $BINANCE_BEST_BID" | bc | awk '{printf "%.2f", $1}') ASK_DIFF=$(echo "$HOLYSHEEP_BEST_ASK - $BINANCE_BEST_ASK" | bc | awk '{printf "%.2f", $1}') echo " Difference: Bid=${BID_DIFF}, Ask=${ASK_DIFF}"

Test 2: Latency Comparison

echo "" echo "2. Latency Comparison (10 samples)..." HOLYSHEEP_LATENCIES="" BINANCE_LATENCIES="" for i in {1..10}; do START=$(date +%s%3N) curl -s -o /dev/null "${HOLYSHEEP_ENDPOINT}/market/ticker?exchange=binance&symbol=BTCUSDT" HOLYSHEEP_LAT=$(($(date +%s%3N) - START)) HOLYSHEEP_LATENCIES="${HOLYSHEEP_LATENCIES}${HOLYSHEEP_LAT} " START=$(date +%s%3N) curl -s -o /dev/null "${BINANCE_ENDPOINT}/api/v3/ticker/price?symbol=BTCUSDT" BINANCE_LAT=$(($(date +%s%3N) - START)) BINANCE_LATENCIES="${BINANCE_LATENCIES}${BINANCE_LAT} " done echo " HolySheep latencies (ms): ${HOLYSHEEP_LATENCIES}" echo " Binance latencies (ms): ${BINANCE_LATENCIES}" echo "" echo "=== Validation Complete ===" echo "If latencies and prices match, proceed to Step 3."

Step 3: Canary Traffic Split (Week 3)

# Step 3: Gradually shift traffic to HolySheep

Update your load balancer configuration

upstream trading_backends { # Official Binance (remaining traffic) server 127.0.0.1:3001 weight=20; # HolySheep relay (canary) server 127.0.0.1:8080 weight=80; }

nginx.conf traffic split

location /api/market { # Week 3: 20% canary set $target "http://127.0.0.1:3001"; # Gradually increase HolySheep weight: # Week 4: 50% canary # Week 5: 100% full cutover proxy_pass $target; proxy_set_header X-Data-Source holy_sheep; }

Step 4: Full Cutover and Key Rotation (Week 4)

# Step 4: Complete cutover and remove official API dependency

1. Remove official Binance API keys from production

(Only if you don't need authenticated endpoints)

2. Update configuration

export DATA_SOURCE=holysheep export HOLYSHEEP_API_KEY=your_rotated_new_key

3. Restart services

docker-compose up -d trading-engine

4. Verify in monitoring dashboard

echo "Migration verification:" curl -s "https://api.holysheep.ai/v1/health" | jq .

Expected output:

{

"status": "healthy",

"infrastructure": "HolySheep AI",

"relay": "Tardis.dev",

"latency_p99": "<50ms"

}

Common Errors and Fixes

Based on production deployments across 30+ teams, here are the most frequent issues and their solutions.

Error 1: WebSocket Connection Timeout

Error Message: WebSocket connection failed: ETIMEDOUT after 30000ms

Root Cause: Network firewall blocking outbound WebSocket connections, or incorrect endpoint URL.

# Fix: Verify WebSocket endpoint and add connection retry logic

const HOLYSHEEP_WS_URL = 'wss://stream.holysheep.ai/v1';

const wsConfig = {
  handshakeTimeout: 10000,  // Reduce from default 30000ms
  maxRetries: 5,
  retryDelay: 1000,  // Exponential backoff starts at 1s

  // For corporate firewalls, try WebSocket over port 443
  options: {
    // Force HTTPS/WSS upgrade
    origin: 'https://api.holysheep.ai'
  }
};

async function connectWithRetry() {
  for (let attempt = 1; attempt <= wsConfig.maxRetries; attempt++) {
    try {
      const ws = new WebSocket(HOLYSHEEP_WS_URL, {
        handshakeTimeout: wsConfig.handshakeTimeout
      });

      await new Promise((resolve, reject) => {
        ws.on('open', resolve);
        ws.on('error', reject);
        setTimeout(() => reject(new Error('Timeout')), wsConfig.handshakeTimeout);
      });

      console.log([HolySheep] Connected on attempt ${attempt});
      return ws;

    } catch (error) {
      console.error([HolySheep] Attempt ${attempt} failed: ${error.message});
      if (attempt < wsConfig.maxRetries) {
        await sleep(wsConfig.retryDelay * Math.pow(2, attempt - 1));
      }
    }
  }
  throw new Error('All connection attempts exhausted');
}

Error 2: Rate Limit Exceeded (429 Status)

Error Message: API rate limit exceeded. Retry-After: 60

Root Cause: Exceeding message quota or hitting endpoint-specific limits.

# Fix: Implement request batching and exponential backoff

class RateLimitedClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.requestsRemaining = Infinity;
    this.resetTime = 0;
  }

  async request(endpoint, params = {}) {
    // Check if we're in a rate limit cooldown
    if (Date.now() < this.resetTime) {
      const waitTime = this.resetTime - Date.now();
      console.log([RateLimit] Waiting ${waitTime}ms before next request);
      await this.sleep(waitTime);
    }

    try {
      const response = await this.makeRequest(endpoint, params);

      // Update rate limit info from headers
      if (response.headers['x-ratelimit-remaining']) {
        this.requestsRemaining = parseInt(response.headers['x-ratelimit-remaining']);
      }
      if (response.headers['x-ratelimit-reset']) {
        this.resetTime = parseInt(response.headers['x-ratelimit-reset']) * 1000;
      }

      return response.data;

    } catch (error) {
      if (error.response?.status === 429) {
        // Respect Retry-After header
        const retryAfter = parseInt(error.response.headers['retry-after']) || 60;
        console.log([RateLimit] Hit limit, backing off for ${retryAfter}s);
        this.resetTime = Date.now() + (retryAfter * 1000);
        await this.sleep(retryAfter * 1000);
        return this.request(endpoint, params); // Retry once
      }
      throw error;
    }
  }

  async makeRequest(endpoint, params) {
    return axios.get(${this.baseUrl}${endpoint}, {
      params,
      headers: { 'X-API-Key': this.apiKey }
    });
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Batch requests to minimize rate limit hits
async function getMultipleTickers(client, symbols) {
  // Good: Use batch endpoint (1 request for 10 symbols)
  const response = await client.request('/market/ticker/batch', {
    exchange: 'binance',
    symbols: symbols.join(',')  // "BTCUSDT,ETHUSDT,SOLUSDT"
  });

  // Bad: Sequential requests (10 requests)
  // for (const symbol of symbols) {
  //   await client.request('/market/ticker', { symbol }); // Hits rate limit!
  // }
}

Error 3: Data Desynchronization (Order Book Mismatch)

Error Message: Order book update rejected: update ID 12345 less than last update ID 12340

Root Cause: WebSocket reconnection caused missed updates during the gap.

# Fix: Implement order book local cache with snapshot refresh

class OrderBookManager {
  constructor(symbol) {
    this.symbol = symbol;
    this.bids = new Map();  // price -> quantity
    this.asks = new Map();
    this.lastUpdateId = 0;
    this.snapshotId = 0;
    this.isInitialized = false;
  }

  // Call this on initial connection
  async loadSnapshot(client) {
    const snapshot = await client.getOrderBook(this.symbol, 1000);

    this.clear();
    this.lastUpdateId = snapshot.lastUpdateId;
    this.snapshotId = snapshot.lastUpdateId;

    snapshot.bids.forEach(([price, qty]) => {
      if (parseFloat(qty) > 0) this.bids.set(price, qty);
    });
    snapshot.asks.forEach(([price, qty]) => {
      if (parseFloat(qty) > 0) this.asks.set(price, qty);
    });

    this.isInitialized = true;
    console.log([OrderBook] Snapshot loaded: ID ${this.lastUpdateId});
  }

  // Apply incremental updates
  applyUpdate(update) {
    if (!this.isInitialized) {
      console.warn('[OrderBook] Update rejected: no snapshot loaded');
      return;
    }

    // Discard updates that arrive before snapshot
    if (update.updateId <= this.lastUpdateId) {
      return;
    }

    // Buffer updates until they exceed snapshot ID
    if (update.updateId > this.snapshotId) {
      // Gap detected: need to reload snapshot
      console.warn([OrderBook] Gap detected: ${update.updateId - this.lastUpdateId} missing updates);
      this.isInitialized = false;
      return;
    }

    // Apply bids
    update.bids.forEach(([price, qty]) => {
      if (parseFloat(qty) === 0) {
        this.bids.delete(price);
      } else {
        this.bids.set(price, qty);
      }
    });

    // Apply asks
    update.asks.forEach(([price, qty]) => {
      if (parseFloat(qty) === 0) {
        this.asks.delete(price);
      } else {
        this.asks.set(price, qty);
      }
    });

    this.lastUpdateId = update.updateId;
  }

  clear() {
    this.bids.clear();
    this.asks.clear();
  }

  getBestBid() {
    const sorted = [...this.bids.keys()].sort((a, b) => parseFloat(b) - parseFloat(a));
    return sorted[0] ? { price: sorted[0], quantity: this.bids.get(sorted[0]) } : null;
  }

  getBestAsk() {
    const sorted = [...this.asks.keys()].sort((a, b) => parseFloat(a) - parseFloat(b));
    return sorted[0] ? { price: sorted[0], quantity: this.asks.get(sorted[0]) } : null;
  }
}

Related Resources

Related Articles