A Strategy Template Allows You to Use WebSocket Market Seamlessly

FMZ QuantFMZ Quant
6 min read

This is a WebSocket market template officially developed by FMZ. Welcome all users to copy and use it: https://www.fmz.com/strategy/470349

Why do we need WebSocket?

At present, the FMZ strategy is mainly based on the traditional REST API encapsulation. Each step of API access requires a network connection to be established, and market data is obtained through polling. This method is simple and easy to use, and it is completely sufficient for most needs.

However, the REST protocol has an inherent delay problem. When multiple trading pairs and multiple-exchange strategies are required, the delay problem will be magnified. Although the Go function of the platform can be executed concurrently, the delay problem still exists, which makes it difficult to meet the needs of relatively high-frequency strategy trading. In addition, if there are too many trading pairs and the polling frequency is too fast, it will encounter the access frequency limit of the trading platform.

Currently, the servers of exchanges are also under heavy burden. They all provide a complete WebSocket protocol and recommend it to API users. Compared with the REST protocol, WebSocket provides a persistent two-way connection method, which enables exchanges to push data to the client in real time, avoiding frequent requests and responses, thus greatly reducing latency. Generally speaking, if the delay in accessing the REST API is around 20ms, the delay in pushing data through WebSocket is about 2ms. In addition, the link to the WebSocket protocol is not limited by the platform access frequency, and it is possible to subscribe to dozens of trading pairs at a time.

Introduction to WebSocket ticker template

FMZ Quant Trading platform has supported WebSocket protocol for a long time, and it is relatively convenient to call, but for novice users, it is still too complicated to handle multiple subscriptions, subscribe to multiple exchange tickers, and embed them efficiently and conveniently into the entire strategy process.
This public WebSocket real-time ticker data acceleration template solves this problem. It is very easy to use and is fully compatible with the current encapsulated API call. For most of the original REST strategies, you can simply modify them and use them directly to accelerate your strategy.

Key Features:

  • Multi-exchange support : This strategy supports WebSocket connections of multiple exchanges, such as Binance, OKX, Bybit, Bitget, etc. Users can follow the packaging method of this template to support more exchanges themselves.

  • Customizable subscriptions : It allows subscription to specific market channels (such as depth, trades, etc.) and efficient processing of received data for immediate use in trading strategies.

  • Advanced error handling : Built-in error tracking and WebSocket reconnection mechanism to ensure the reliability and continuity of data flow.

A brief introduction to the implementation principle

Note that this strategy uses TypeScript. If you are only familiar with JavaScript, it may look a bit strange. TypeScript introduces a type system and richer language features based on JavaScript. For applications such as quantitative trading that need to handle complex logic, using TypeScript can reduce potential errors and improve the readability and maintainability of the code. Therefore, it is recommended to learn it briefly.

In addition, the strategy uses the asynchronous mechanism of the FMZ platform. The child thread can send messages to the main thread through the threadPostMessage function. This method is asynchronous and is suitable for notifying the main thread of data updates generated in the child thread. The main thread and the child thread can share data through the threadGetData and __threadSetData functions. This method allows threads to access and modify shared states. If you want to learn about multithreading, combined with the platform documentation, this strategy is also a good learning example.

The main principle of this strategy is to connect to mainstream digital currency exchanges through WebSocket and receive market data (such as depth information and transaction information) in real time to provide data support for quantitative trading decisions. The specific implementation process is as follows:

1. WebSocket connection settings
The function setupWebsocket is used to initialize a WebSocket connection and receive market data. It receives a parameter main_exchanges, indicating the exchange to connect to.

  • MyDial function : Create a WebSocket connection, record the connection time, and output the close time when closing the connection.

  • updateSymbols function : Check regularly whether there are new subscription requests and update the current trading pair list as needed.

2. Data processing
The object supports defines the supported exchanges and their processing function (such as Binance). The processing function for each exchange is responsible for parsing the received message and extracting the relevant data.

  • processMsg function : Process messages from exchanges, identify different types of data (such as depth updates, transactions, etc.), and format them into a unified event object.

3. Subscription data
At each connection, the system will subscribe to the relevant market data channels based on the current trading pair.

  • getFunction function : Get the corresponding processing function according to the exchange name.

  • this.wssPublic function : Initialize the WebSocket connection and start receiving data.

4. Thread management
Start a thread for each exchange, receive data in real-time and process the data through callback functions.

  • threadMarket function : Receive data in a child thread, parse and store the latest depth and transaction information.

5. Rewrite the data acquisition method
Rewrite the methods for obtaining depth and trading information for each exchange, giving priority to returning data that is updated in real-time.

How to use the template

  1. Initialization : Use $.setupWebsocket() to initialize the WebSocket connection of the target exchange.

  2. Subscription : The system will subscribe to relevant channels (such as depth, trading, etc.) automatically for the products you trade.

  3. Data acquisition : By calling the GetDepth() and GetTrades() functions, the market depth and transaction records are automatically returned using WebSocket real-time data.

  4. Error handling : The strategy includes a tracking mechanism to log connection and data errors, and attempts to reconnect automatically if the connection is lost.

If the EventLoop() function is added to the strategy, it will be changed to a trigger mechanism. When there is wss data update, it will automatically obtain it immediately, and wait if there is no latest data. It is equivalent to an intelligent Sleep function. Of course, you can also use Sleep directly.

function main() {
    $.setupWebsocket()
    while (true) {
        exchanges.map(e=>{
            Log(e.GetName(), e.GetDepth())
            Log(e.GetName(), e.GetTrades())
        })
        EventLoop(100) // trigger by websocket
    }
}

Refer to my previous multi-currency trading strategy guide: https://www.fmz.com/bbs-topic/10508 , which can be modified easily to support WebSocket:

function MakeOrder() {
    for (let i in Info.trade_symbols) {
        let symbol = Info.trade_symbols[i];
        let buy_price = exchange.GetDepth(symbol + '_USDT').Asks[0].Price;
        let buy_amount = 50 / buy_price;
        if (Info.position[symbol].value < 2000){
            Trade(symbol, "buy", buy_price, buy_amount, symbol);
        }
    }
}

function OnTick() {
    try {
        UpdatePosition();
        MakeOrder();
        UpdateStatus();
    } catch (error) {
        Log("loop error: " + error);
    }
}

function main() {
    $.setupWebsocket()
    InitInfo();
    while (true) {
        let loop_start_time = Date.now();
        if (Date.now() - Info.time.last_loop_time > Info.interval * 1000) {
            OnTick();
            Info.time.last_loop_time = Date.now();
            Info.time.loop_delay = Date.now() - loop_start_time;
        }
        Sleep(5);
    }
}
0
Subscribe to my newsletter

Read articles from FMZ Quant directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

FMZ Quant
FMZ Quant

Quantitative Trading For Everyone