发明者数字货币量化平台websocket使用指南(Dial函数升级后详解)
Author:
小草
, Created: 2019-04-01 11:06:09, Updated: 2019-12-04 10:41:25
基本上所有数字货币交易所都支持websocket发送行情,部分交易所支持websocket更新账户信息。相比于rest API, websocket一般具有延时低,频率高,不受平台rest API频率限制等有带你,缺点是有中断问题,处理不直观。关于websocket简介,可以参考我曾经的这篇文章:
https://zhuanlan.zhihu.com/p/22693475
本文将主要介绍在FMZ发明者量化平台,使用JavaScript语言,使用平台封装的Dial函数进行连接,具体说明和参数在文档,搜索Dial,为了实现各种功能,Dial函数进行了几次更新,本文将涵盖这一点,并介绍基于wss的事件驱动的策略,以及连接多交易所问题。
1.websocket连接:
一般直接连接即可,如获取币安全ticker推送:
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中的,如刚才币安的例子,很方便,推荐使用。对于需要发送订消息的,可以自己维护重连机制。
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.websocket读取:
一般在死循环中不断读取即可,代码如下:
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数据
wss数据推送速度很快,Go的底层会把所有的数据缓存在队列中,等程序调用read时,再依次返回。而机器人的下单等操作会带来延时,可能会造成数据的累积。对于成交推送,账户推送,深度插值推送等这类信息,我们需要历史数据,对于行情数据,我们大部分情况只关心最新的,不关心历史数据。
read()如果不加参数,会返回最旧的数据,没数据时阻塞到返回。如果想要最新数据,可以用client.read(-2)立即返回最新数据,但再没数据时回返回null,需要判断再引用。
根据如何对待缓存的旧数据,以及无数据时是否堵塞,read有不同的参数,具体如下图,看起来很复杂,但让程序更加灵活。
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) // 参数-1代表无数据立即返回null,不会阻塞到有数据返回
var msgCoinbase = coinbase.read(-1)
if(msgBinance){
// 此时币安有数据返回
if(msgCoinbase){
// 此时coinbase有数据返回
Sleep(1) // 可以休眠1ms
4.断线重连问题:
这部分处理较为麻烦,因为推送数据可能中断,或者推送延时极高,即使能接收到heartbeat也不代表数据还在推送,可以设置一个事件间隔,如果超过间隔没有收到更新就重新连接,并且最好隔一段时间和rest返回的结果对比,看数据是否准确。对于币安这种特殊情况,直接设置自动重连即可。
5.使用websocket的一般程序框架:
由于已经使用了推送数据,程序自然也要写成事件驱动,注意推送数据频繁,不用过多请求导致被封,一般可以写成:
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)
6.总结:
各个交易所的websocket的连接方式,数据发送方式,可订阅的内容,数据格式往往不相同,所以平台并没有进行封装,需要用Dial函数自行连接。本文基本涵盖了一些基本的注意事项,如果还有问题,欢迎提问。
PS.一些交易所虽然没有提供websocket行情,但实际上登陆网站使用调式功能,会发现都是使用的websocket推送,研究一下就会发现订阅格式和返回格式。有些看起来像是加密过,用base64解码再解压就可以看到了。
FMZ研究平台Python入门指南
FMZ量化平台一些值得学习的比特币及数字货币量化策略
Make Post-Only order and bulk orders on BitMEX through IO
关于如何在BitMEX挂仅被动成交做市单和批量下单(IO范例)
Linux托管者安装和升级最佳方法
FMZ量化平台这些功能你知道吗?
BitMEX挂单策略详解
CoinPark通用协议Python2版本
BitMEX exchange API note
X 分钟速成 Python
FMZ beginer tutorial
BitMEX exchange API note
1.1 What is quantitative trading?
Quantitative trading quick start
请求交易所API,偶尔出现 Timeout
Implementing MACD in Python
OKEX get depth 报错
回测问题请教
ZBG交易所不能用
小白问题,怎么用blockly可视化编程下市价交易单?
获取robotdetail接口里的参数3是啥意思
How can newcomers go through the road, how to capture trends and make profits last?
Beginner's Guide to Time Series Analysis
Backtesting a Forecasting Strategy for the S&P500 in Python with pandas
“Always understand when to quit” – 6 exit strategies
FMZ公众号互动
What are the Different Types of Quant Funds?
Backtesting An Intraday Mean Reversion Pairs Strategy Between SPY And IWM
Backtesting a Moving Average Crossover in Python with pandas
How to Identify Algorithmic Trading Strategies
xaifer48 wss连接运行一段时间后,报“ json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)”这个错误,请问大神要如何处理?已经设置了自动重连,需要再手动写一个重连么@小草
haohao 币安永续合约为什么 连接完,定阅账户信息变动,一分钟后 read 就返回空了
xaifer48 收到,谢谢
小草 解析错误,把消息打印出来看看,做个容错就行
韬奋量化 因为币安规定,只有账号信息有变动时才会推送信息。是这样吧?