Básicamente todos los intercambios de moneda digital soportan el envío de websocket, algunos intercambios soportan la información de la cuenta de actualización de websocket. En comparación con la API de reposo, websocket generalmente tiene baja latencia, alta frecuencia, no está limitado por la frecuencia de la API de reposo de la plataforma. https://zhuanlan.zhihu.com/p/22693475
Este artículo se enfocará principalmente en la plataforma de cuantificación de los inventores de FMZ, el lenguaje JavaScript, el uso de la función Dial en la plataforma para conectar, las especificaciones y los parámetros en la documentación, la búsqueda de Dial, la función Dial se ha actualizado varias veces para implementar varias funciones, este artículo cubrirá esto, y presentará las estrategias de accionamiento de eventos basadas en wss, y el problema de conectar múltiples exchanges.
Por lo general, las conexiones son directas, por ejemplo, para obtener un ticker de seguridad de la moneda:
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
Para que los datos devueltos sean en formato comprimido, es necesario especificar el formato comprimido en la conexión, comprimir especifica el formato comprimido, y el modo representa el envío de los datos devueltos que requieren compresión, como en la conexión OKEX:
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
La función Dial soporta la reconexión, realizada por el lenguaje Go de nivel inferior, la detección de la conexión interrumpida y la reconexión de la reunión, es conveniente para el contenido de los datos de la solicitud ya en la url, como el ejemplo de Binance. Se recomienda su uso. Para aquellos que necesitan enviar mensajes por encargo, puede mantener su propio mecanismo de reconexión.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
Para suscribirse a las noticias de wss, algunos intercambios solicitan en la url, y algunos canales necesitan suscripciones propias, como coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
En general, se puede leer continuamente en el ciclo de muerte, y el código es el siguiente:
function main() {
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
while (true) {
var msg = client.read()
var data = JSON.parse(msg) //把json字符串解析为可引用的object
// 处理data数据
}
}
La velocidad de envío de datos de wss es muy rápida, la base de Go guarda todos los datos en una cola, y cuando un programa llama a read, los devuelve en secuencia. Mientras que las operaciones de orden de un robot traen un retraso, lo que puede causar acumulación de datos. Para envío de transacciones, envío de cuentas, envío de inserciones de profundidad, etc., necesitamos datos históricos, y para datos reales, en la mayoría de los casos solo nos interesamos en los últimos, no nos interesan los datos históricos.
read() si no se agrega ningún parámetro, se devuelve el dato más antiguo, si no hay datos se bloquea hasta que se devuelva. Si se desea el dato más reciente, se puede usar client.read(-2) para devolver el dato más reciente de inmediato, pero si no hay más datos, se devuelve null, se necesita un juicio y otra referencia.
Dependiendo de cómo se traten los datos antiguos almacenados en la caché, y si se bloquean cuando no hay datos, read tiene diferentes parámetros, como se muestra a continuación, que parecen complicados, pero hacen que el programa sea más flexible.
Para este tipo de situaciones, el procedimiento no puede utilizar el simple read (), ya que una plataforma bloqueará el mensaje en espera, mientras que la otra plataforma no recibirá el mensaje, incluso si hay un nuevo mensaje. El procedimiento general es:
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) // 参数-1代表无数据立即返回null,不会阻塞到有数据返回
var msgCoinbase = coinbase.read(-1)
if(msgBinance){
// 此时币安有数据返回
}
if(msgCoinbase){
// 此时coinbase有数据返回
}
Sleep(1) // 可以休眠1ms
}
}
Esta parte del procesamiento es un poco problemática, ya que el envío de datos puede interrumpirse o el retraso en el envío es muy alto, incluso si se puede recibir el latido del corazón no significa que los datos se estén enviando, se puede configurar un intervalo de eventos, si no se reciben actualizaciones después del intervalo, se vuelve a conectar, y es mejor comparar el resultado con el resto devuelto a intervalos de tiempo para ver si los datos son precisos. Para esta situación especial, se puede configurar directamente la reconexión automática.
Como ya se han utilizado datos de empuje, el programa también debe escribirse como un evento, teniendo en cuenta que los datos de empuje son frecuentes y no se bloquean con demasiadas solicitudes, por lo general se puede escribir como:
var tradeTime = Date.now()
var accountTime = Date.now()
function trade(data){
if(Date.now() - tradeTime > 2000){//这里即限制了2s内只交易一次
tradeTime = Date.now()
//交易逻辑
}
}
function GetAccount(){
if(Date.now() - accountTime > 5000){//这里即限制了5s内只获取账户一次
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)
}
}
El modo de conexión, el modo de envío de datos, el contenido de suscripción y el formato de datos de los websockets de las distintas plataformas suelen ser diferentes, por lo que las plataformas no se envasan, sino que se conectan por sí mismas con la función Dial. Este artículo cubre básicamente algunas de las precauciones básicas.
PS. Algunos intercambios, aunque no ofrecen la configuración de websocket, en realidad usan la función de configuración al acceder al sitio web y descubren que se utiliza el envío de websocket, si se investiga, se encuentra el formato de suscripción y el formato de retorno. Algunos parecen cifrados y se pueden ver descifrados con base64 .