기본적으로 모든 디지털 화폐 거래소는 websocket 전송 방식을 지원하고, 일부 거래소는 websocket 업데이트 계정 정보를 지원한다. rest API에 비해, websocket는 일반적으로 지연이 낮고, 주파수가 높으며, 플랫폼rest API 주파수 제한에 의해 제한되지 않는다. 단점은 중단 문제가 있고, 처리 직관적이지 않다. https://zhuanlan.zhihu.com/p/22693475
이 문서는 주로 FMZ 발명자의 양적 플랫폼에 대해 설명할 것이며, JavaScript 언어를 사용하여, 플랫폼의 패키지된 Dial 함수를 사용하여 연결합니다. 설명과 매개 변수는 문서에 나와 있으며, Dial을 검색합니다. 다양한 기능을 구현하기 위해 Dial 함수는 여러 번 업데이트되었습니다.
일반적으로 직접 연결할 수 있는데, 예를 들어, 화폐 보안 티커를 전송할 수 있습니다.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
복귀 데이터의 압축 형식은 연결에서 지정해야 하며, compress은 압축 형식을 지정하고, modde는 복귀 데이터를 전송하는 데 압축이 필요한 것을 나타냅니다. 연결 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")
일부 거래소들의 요청은 url에 있고, 일부 거래소들은 Coinbase와 같은 채널에 직접 가입해야 합니다.
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
이 코드들은 일반적으로 죽은 순환에서 계속 읽을 수 있습니다.
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에는 다른 파라미터가 있다. 구체적으로 아래 그림처럼, 복잡하게 보이지만 프로그램을 더 유연하게 한다.

이러한 경우의 절차는 간단하게 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
}
}
이 부분 처리에는 다소 번거로움이 있는데, 푸싱 데이터가 중단될 수도 있고, 혹은 푸싱 지연이 매우 높기 때문에, heartbeat를 수신할 수 있더라도 데이터가 계속 푸싱되고 있다는 것을 의미하지 않는다. 하나의 이벤트 간격을 설정할 수 있으며, 간격이 넘어서도 업데이트를 받지 못하면 다시 연결하고, 시간이 지나면 rest과 반환된 결과와 비교하여 데이터가 정확하는지 확인하는 것이 좋다. 동전 안의 이 특별한 경우에, 직접 자동 재 연결을 설정할 수 있다.
푸시 데이터를 사용했기 때문에, 프로그램은 자연스레 이벤트 드라이브로 작성해야 합니다. 푸시 데이터가 자주 발생하여 너무 많은 요청으로 인해 차단되지 않도록 주의하십시오. 일반적으로 다음과 같이 쓸 수 있습니다.
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)
}
}
각 거래소의 웹소켓의 연결 방식, 데이터 전송 방식, 구독할 수 있는 내용, 데이터 포맷은 서로 다르기 때문에 플랫폼은 패키징이 되지 않고 다이얼 함수를 사용하여 자동으로 연결해야 합니다. 이 글은 기본적으로 몇 가지 기본적인 주의 사항을 다루고 있으며, 질문이 있으면 문의하시기 바랍니다.
PS. 일부 거래소에서는 websocket 행렬이 제공되지 않지만, 실제로 웹사이트에 로그인할 때 websocket 푸싱 기능이 사용되고 있는 것을 볼 수 있습니다. 검색을 하면 서브스크립트 포맷과 리턴 포맷이 발견됩니다.