Simulated Exchange Design Doc
Source: Notion | Last edited: 2025-02-06 | ID: f6cb4425-530...
Introduction
Section titled “Introduction”What is a Simulated Exchange?
A simulated exchange is a crypto exchange simulator. It simulates operations (buy crypto, sell crypto, query account info, etc.) between a client and the exchange. In addition, the simulator can also expedite the backtesting process from a couple of years into a couple of hours.
Why build a Simulated Exchange?
Building a simulated exchange can help us test different strategies to improve the execution performance and lower the slippage.
What’s the difference between the Simulated Exchange and Model backtesting?
It differs in data granularity and the ability to test event-driven strategies.
Model backtesting uses the prices of candle sticks per minute to simulate order results. More specifically, the average price of the minute is used to calculate the average order-filled price. And a fixed trading fee is used to calculate the trading cost and slippage, which is not accurate.
Meanwhile, the simulated exchange uses 100ms-level orderbook and trades data to simulate the operations (buy/sell/query). It’s more accurate in terms of order-filled price, order types (maker vs taker), and is able to test event-driven trading strategies. (i.e. market-making order is an example of an event-driven strategy. The basic logic is based on order_fill_event to create an opposite-side order with spread)
How to simulate a request in the past?
First, load past n years’ data into the simulated exchange. Then the client can send a request with a timestamp in the past to simulate a request in the past. The exchange simulator should be able to execute the business logic and send a response.
How to simulate a websocket message? (NEED TO BE DISCUSSED)
If we choose to simulate websocket message, we’d focus on “Order” and “Trade” events. (Orderbook websocket event can be eliminated by using a REST GET operation. Simulator needs to calculate snapshots in ms beforehand). Once the client sends a new order request to the simulator, the simulator not only returns the current order status (NEW, FILLED or CANCELED), but also returns when would the order get filled in the future with max fast-forward constraint. ( i.e. if fast-forward constraint is 30 min, the response only needs to tell if the order can be filled in the next 30 min). The client side would save the future order-filled events (if any) into a time-based priority queue. Then the client may fast-forward to the next order-filled event. Thus, a websocket event simulation is done.
Challenges:
- Websocket simulation. We have a brainstorming idea of using a time-based priority queue to simulate websocket event. It’s not a concrete plan yet.
- Fast simulation. We hope to make the simulation as fast as possible so that we can test different execution strategies.
- Massive refactor. We use CCXT library as a API adaptor to communicate with crypto exchange (i.e. Binance). We may not use existing code without a lot of refactoring. CCXT has unified method signature and response parsing functions. I can think of adding timestamp to every request, and there may be other refactoring needed. In addition, our current code mixed business logic into the Binance service (BinanceTrader) which makes the refactor more work.
- How to simulate market impact (slippage)? Is Orderbook data enough? Should Trades data also be used? and how?
API Design
Section titled “API Design”The simulated exchange serves one client at a time. The required endpoints are listed below. It’s responsible for:
- Calculate user’s balance, commission, order status, and maintain order/trade history etc.
- Generate a detailed report in the end of the simulation. i.e. what’s the balance over time, max drawdown, slippage, Sharpe ratio, Calmar ratio, Sortino ratio, etc.
- Database: Simulated Exchange
Ref:
- Binance Future API: https://binance-docs.github.io/apidocs/futures/en/
Notes:
- Market order return executed result immediately.