Exchange Executor Abstraction
Deep dive into the ExchangeExecutor Protocol, CCXT integration with exchange-specific adaptations, rate limiting, order placement pipeline, and the Paper Trading sandbox simulator.
DepthSight uses a clean abstraction layer to decouple the strategy runner from raw exchange APIs. The system relies on a Python Protocol called ExchangeExecutor to guarantee static typing boundaries while allowing multiple execution strategies โ live exchanges, paper trading, and mock testing.
ExchangeExecutor Protocol
The ExchangeExecutor (bot_module/exchanges/base.py, ~59 lines) is a static Python Protocol defining the standard interaction contract. Any backend implementation (Binance, Bybit, Paper Trading) must satisfy these methods.
Protocol Signature
Sources:The protocol uses typing.Protocol (structural subtyping) โ any class implementing all these methods with matching signatures satisfies the contract without explicit inheritance. This enables easy mocking and testing.
CCXT Implementation (CCXTExecutor)
The CCXTExecutor (bot_module/exchanges/ccxt_executor.py, ~2,068 lines) is the primary production executor. It uses the asynchronous CCXT Pro library to communicate with target exchanges.
Order Placement Pipeline (place_order(), lines 605โ889)
The order placement process involves 11 steps:
Step 1 โ Symbol Normalization (line 608):
Sources:Step 2 โ Order Type Mapping: Binance order types are mapped to CCXT equivalents:
| Binance Type | CCXT Type | Notes |
|---|---|---|
MARKET | "market" | Standard market order |
LIMIT | "limit" | Limit order with price |
STOP_MARKET | "market" | + triggerPrice or stopLossPrice param |
TAKE_PROFIT_MARKET | "market" | + takeProfitPrice param |
TRAILING_STOP_MARKET | "market" | + callbackRate param |
Step 3 โ Exchange-Specific Trigger Parameters: Each exchange handles stop/trigger orders differently:
| Exchange | Trigger Param | Notes |
|---|---|---|
| Binance Futures | stopPrice, workingType | Standard stop-market |
| Bybit | triggerPrice, triggerDirection | Direction 1=up, 2=down |
| Bitget | stopLossPrice / takeProfitPrice | Separate SL/TP params |
| Gate.io | stopLossPrice / takeProfitPrice | + settle: "usdt" |
| BingX | stopLossPrice | Sandbox needs hedge mode |
| OKX | posSide | Required for futures |
Step 4 โ Binance Futures Algo Orders (lines 726โ819):
For STOP_MARKET, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET on Binance Futures, the executor bypasses CCXT's create_order and calls fapiPrivatePostAlgoOrder directly for algo order placement:
Step 5 โ Rate Limit Compliance:
CCXT's built-in enableRateLimit: True manages request timing. No custom rate limiting logic is needed โ CCXT handles token bucket per-exchange internally.
Step 6 โ Response Mapping (line 883):
The raw CCXT order is mapped to a Binance-compatible response via _map_ccxt_order_to_binance() (lines 1933โ1991), ensuring the controller receives a consistent format regardless of the underlying exchange.
Balance Fetching (get_account_balance(), lines 1365โ1477)
Sources:
For BingX sandbox (lines 1410โ1470), a special fallback chain tries multiple field names (availableMargin, availableBalance, maxWithdrawAmount, trialFundBalance, etc.) due to the sandbox's non-standard response format.
Exchange Info Caching (fetch_exchange_info(), lines 521โ603)
Exchange market info is cached via CCXT's load_markets():
Individual symbol filters are accessible via:
get_tick_size(symbol)โ price increment precisionget_lot_size_params(symbol)โ quantity step size, min/maxget_min_notional(symbol)โ minimum order value
WebSocket User Data Stream
The executor manages exchange-specific user data streams (account updates, order fills):
Sources:Paper Trading Simulator (PaperTradingExecutor)
To test strategies with zero risk, DepthSight includes a local matching engine sandbox.
Architecture
Strategy Signal -> PaperTradingExecutor
|
โโ Virtual Balance Check (paper_wallets table)
โโ Market Data Matching (live DataConsumer L2 book)
โโ Fill Simulation (price overlap detection)
โโ Trade Recording (trades table, trade_mode="PAPER")
Key Features
| Feature | Implementation |
|---|---|
| Virtual Balances | Stored in paper_wallets table โ per-user, per-asset |
| Order Matching | Limit orders filled when simulated ticker overlaps order price |
| Market Orders | Filled immediately at next available price + simulated slippage |
| L2 Book Integration | Uses live DataConsumer Level 2 updates for fill precision |
| Execution Parity | Implements the exact ExchangeExecutor protocol โ switching a bot from paper to live requires changing one config parameter (mode: "live") |
Execution Parity
Because PaperTradingExecutor implements the exact same ExchangeExecutor protocol as CCXTExecutor, the TradingController is completely agnostic to which executor is active:
This design guarantees zero drift between backtest/paper and live performance.
Executor Factory
The create_exchange_executor() factory function (bot_module/exchanges/factory.py) dynamically selects the correct implementation based on exchange ID:
| exchange_id | Executor Class | Notes |
|---|---|---|
binance | CCXTExecutor | Futures + Spot, testnet support via _patch_binance_demo_urls() |
bybit | CCXTExecutor | Linear inverse + spot |
bitget | CCXTExecutor | Hedge mode + one-way mode fallback |
gateio | CCXTExecutor | Swap + spot with settle param |
bingx | CCXTExecutor | Sandbox with special balance parsing |
paper | PaperTradingExecutor | Local sandbox, no exchange connection |
Database Schema and Models
Comprehensive reference of all PostgreSQL tables, SQLAlchemy ORM models, relationships, indexes, and constraints managed by Alembic migrations.
Deployment & Scaling
System design guide for scaling DepthSight to handle thousands of concurrent users โ horizontal scaling, Redis splitting, sharded bot processes, PgBouncer integration, and the stateless architecture.