В процессе загрузки ресурсов... загрузка...

FMZ Cryptocurrency Quantitative Platform WebSocket Usage Guide (подробное объяснение обновленной функции набора)

Автор:FMZ~Lydia, Создано: 2023-07-13 14:03:32, Обновлено: 2024-01-03 21:05:36

img

FMZ Cryptocurrency Quantitative Platform WebSocket Usage Guide (подробное объяснение обновленной функции набора)

Большинство криптовалютных бирж поддерживают отправку рыночных данных через WebSocket, а некоторые биржи также поддерживают обновление информации об аккаунте через WebSocket. По сравнению с REST API, WebSocket обычно имеет более низкую задержку, более высокую частоту и не подчиняется ограничениям скорости API платформы.

В этой статье в основном будет представлено использование функции Dial, которая инкапсулирована в платформе FMZ Quant с использованием языка JavaScript. Конкретные инструкции и параметры можно найти в документации путем поиска Dial. Для достижения различных функциональностей функция Dial была обновлена несколько раз, которые будут рассмотрены в этой статье. Кроме того, в ней также будет обсуждаться стратегия, основанная на событиях, основанная на WebSocket Secure (wss) и вопрос подключения к нескольким биржам.

Подключение веб-сокета:

Обычно достаточно прямого подключения, например, чтобы получить тикер безопасности монеты:

var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")

Когда возвращенные данные в сжатом формате, они должны быть указаны во время подключения. compress используется для указания формата сжатия, а mode представляет собой, какая часть данных (отправляющая или возвращающаяся) должна быть сжата. Например, при подключении к OKEX можно использовать следующее:

var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")

Функция Dial поддерживает воссоединение, которое обрабатывается базовым языком Go. Она автоматически воссоединяется, когда обнаруживается, что соединение отключено. Для случаев, когда данные запроса уже включены в URL-адрес, такие как предыдущий пример с Binance, она очень удобна и рекомендуется использовать. Однако для случаев, когда требуется отправка подписки сообщений, рекомендуется поддерживать механизм воссоединения вручную.

var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")

Подпишитесь на wss сообщения, некоторые биржи имеют запросы в URL, и есть также каналы, которые вы должны отправить свои собственные подписки, такие как coinbase:

client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')

2. Читать веб-сокет

Как правило, его можно читать непрерывно в бесконечной петле.

function main() {
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
    while (true) {
        var msg = client.read()
        var data = JSON.parse(msg) // Parse json strings into quotable objects 
// Process data 
    }
}

Скорость продвижения данных wss очень быстрая. Подслой Golang будет кэшировать все данные в очереди, и когда вызовы программы будут прочитаны, данные будут возвращены в свою очередь. Однако такие операции, как размещение заказа на боте, вызовут задержки, что может привести к накоплению данных. Для информации, такой как продвижение исполнения торговли, продвижение счета и продвижение глубины интерполяции, нам нужны данные истории. Для данных рынка котировок в большинстве случаев мы заботимся только о последних данных, а не о данных истории.

Если read() не добавляет параметров, он вернет старейшие данные и блокирует до возвращения, когда нет данных. Если вы хотите получить последние данные, вы можете использовать client.read(-2) для немедленного возвращения последних данных, но когда нет данных, он вернет null, который необходимо оценить перед ссылкой.

В зависимости от того, как обращаться со старыми кэшированными данными и блокируется ли она, когда нет данных, read имеет разные параметры, как показано в таблице ниже, что выглядит сложно, но делает программу более гибкой.

img

3. Подключение к нескольким платформам с помощью Websocket

В этом случае очевидно, что просто использование read() не работает в программе, потому что одна платформа заблокирует ожидающие сообщения, а другая платформа не будет принимать даже если есть новые сообщения.

    function main() {
        var binance = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
        var coinbase = Dial("wss://ws-feed.pro.coinbase.com", 60)
        coinbase.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
        while (true) {
            var msgBinance = binance.read(-1) // Parameter -1 represents no data and return null immediately; it will not occur that being blocked before there is data to be returned 
            var msgCoinbase = coinbase.read(-1)
            if(msgBinance){
                // at this time, Binance has data to return 
            }
            if(msgCoinbase){
                // at this time, coinbase has data to return 
            }
            Sleep(1) // Sleep for 1 millisecond
        }
    }

4. Проблемы с отключением и воссоединением

Эта часть обработки является более проблематичной, поскольку данные могут быть прерваны или задержка продлится чрезвычайно долго. Даже если можно получить сердцебиение, это не означает, что данные все еще подталкиваются. Вы можете установить интервал событий; если после интервала не будет получено обновления, перезагрузите; лучше сравнить результаты, возвращенные rest через определенный период времени, чтобы увидеть, точны ли данные.

5. Использование общих программных рамок Websocket

Для push-данных, которые были использованы, программа естественно будет записываться как вызванная событием; обратите внимание на частоту push-данных, потому что высокочастотные запросы приведут к блокировке; как правило, вы можете написать:

    var tradeTime = Date.now()
    var accountTime = Date.now()
    function trade(data){
        if(Date.now() - tradeTime > 2000){//Here it limits only one trade in 2 seconds 
            tradeTime = Date.now()
            // Trading logic
        }
    }
    function GetAccount(){
        if(Date.now() - accountTime > 5000){//Here it limits GetAccount only once in 5 seconds 
            accountTime = Date.now()
            return exchange.GetAccount()
        }
    }
    function main() {
        var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true");
        while (true) {
            var msg = client.read()
            var data = JSON.parse(msg)
            var account = GetAccount()
            trade(data)
        }
    }

6. Заключение

Способ подключения, способ передачи данных, подписанный контент и формат данных веб-сокета на каждой платформе часто различаются, поэтому платформа не инкапсулирует его и должна использовать функцию Dial для подключения самостоятельно.

PS: Несмотря на то, что некоторые платформы не предоставляют цитаты websocket, на самом деле, когда вы входите на сайт, чтобы использовать функцию отладки, вы обнаружите, что все они используют push websocket.


Больше