Về cơ bản, tất cả các sàn giao dịch tiền kỹ thuật số đều hỗ trợ websocket để gửi thông tin, một số sàn giao dịch hỗ trợ websocket để cập nhật thông tin tài khoản.https://zhuanlan.zhihu.com/p/22693475
Bài viết này sẽ chủ yếu giới thiệu về nền tảng định lượng của FMZ, sử dụng ngôn ngữ JavaScript, kết nối với hàm Dial được đóng gói trên nền tảng, thông tin cụ thể và tham số trong tài liệu, tìm kiếm Dial, để thực hiện các chức năng khác nhau, hàm Dial đã được cập nhật một vài lần, bài viết này sẽ bao gồm điều này và giới thiệu các chiến lược điều khiển sự kiện dựa trên wss, và các vấn đề liên kết nhiều sàn giao dịch.
Thông thường, người dùng có thể kết nối trực tiếp, ví dụ:
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
Đối với dữ liệu được trả về là định dạng nén, cần thiết trong kết nối được chỉ định, compress chỉ định định dạng nén, mode đại diện cho việc gửi dữ liệu được trả lại cần nén, ví dụ như kết nối OKEX:
var client = Dial("wss://real.okex.com:10441/websocket?compress=true|compress=gzip_raw&mode=recv")
Chức năng Dial hỗ trợ nối lại, được thực hiện bởi ngôn ngữ Go dưới cùng, kết nối bị ngắt và nối lại được phát hiện, rất thuận tiện, nên sử dụng cho nội dung dữ liệu yêu cầu đã có trong url, ví dụ như ví dụ của Binance. Đối với những người cần gửi tin nhắn, bạn có thể tự duy trì cơ chế nối lại.
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr|reconnect=true")
Một số kênh khác cũng yêu cầu bạn đăng ký, chẳng hạn như Coinbase:
client = Dial("wss://ws-feed.pro.coinbase.com", 60)
client.write('{"type": "subscribe","product_ids": ["BTC-USD"],"channels": ["ticker","heartbeat"]}')
Thông thường, trong chu kỳ chết, các mã được đọc liên tục như sau:
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 dữ liệu đẩy rất nhanh, tầng dưới của Go sẽ trì hoãn tất cả dữ liệu trong hàng đợi, chờ cho chương trình gọi read, và sau đó quay trở lại. Trong khi đó, các hoạt động của robot sẽ gây ra sự trì hoãn, có thể gây ra sự tích lũy dữ liệu. Đối với giao dịch đẩy, tài khoản đẩy, sâu nhập đẩy, và các thông tin như vậy, chúng ta cần dữ liệu lịch sử, đối với dữ liệu thị trường, hầu hết các trường hợp chúng ta chỉ quan tâm đến dữ liệu mới nhất, không quan tâm đến dữ liệu lịch sử.
read ((() nếu không thêm tham số, sẽ trả về dữ liệu cũ nhất, nếu không có dữ liệu, chặn để trả về. Nếu muốn dữ liệu mới nhất, bạn có thể sử dụng client.read (((-2) để trả về dữ liệu mới nhất ngay lập tức, nhưng nếu không có dữ liệu, nó sẽ trả về null, bạn cần phải quyết định tham khảo lại.
Theo cách xử lý dữ liệu cũ được lưu trữ và liệu có bị tắc khi không có dữ liệu, read có các tham số khác nhau, cụ thể như hình dưới, trông phức tạp nhưng giúp cho chương trình linh hoạt hơn.
Đối với trường hợp này, rõ ràng là không thể sử dụng đơn giản read (), bởi vì một sàn giao dịch sẽ tắc nghẽn thông báo chờ, trong đó sàn giao dịch khác sẽ không nhận được thông báo ngay cả khi có thông báo mới.
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
}
}
Phần xử lý này khá khó khăn vì dữ liệu đẩy có thể bị gián đoạn, hoặc thời gian đẩy quá cao, thậm chí nếu nhận được nhịp tim cũng không có nghĩa là dữ liệu vẫn đang được đẩy, bạn có thể thiết lập một khoảng thời gian sự kiện, nếu vượt quá khoảng thời gian không nhận được bản cập nhật, bạn sẽ kết nối lại, và tốt nhất bạn nên phân biệt một khoảng thời gian và kết quả rest trở lại để xem dữ liệu có chính xác hay không. Đối với trường hợp đặc biệt như Bitcoin, bạn có thể đặt tự động nối lại trực tiếp.
Vì đã sử dụng dữ liệu đẩy, các chương trình tự nhiên cũng phải được viết như một trình điều khiển sự kiện, hãy chú ý đẩy dữ liệu thường xuyên, không cần quá nhiều yêu cầu dẫn đến khóa, thường có thể được viết như sau:
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)
}
}
Cách kết nối của các socket web của các sàn giao dịch khác nhau, cách gửi dữ liệu, nội dung có thể đăng ký, định dạng dữ liệu thường khác nhau, vì vậy nền tảng không được đóng gói và cần tự kết nối bằng chức năng Dial.
PS. Một số sàn giao dịch mặc dù không cung cấp thị trường websocket, nhưng thực sự sử dụng chức năng phím để truy cập trang web, bạn sẽ thấy tất cả các websocket được sử dụng để đẩy, tìm hiểu và bạn sẽ thấy định dạng đăng ký và định dạng trả về. Một số trông giống như được mã hóa, có thể được giải mã bằng base64.
xaifer48Sau khi kết nối wss chạy trong một thời gian, báo hiệu json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) báo hiệu lỗi này, xin hỏi Đức Chúa Trời sẽ xử lý như thế nào?
haohaoTại sao các hợp đồng vĩnh cửu của Binance được kết nối, thông tin tài khoản được đọc thay đổi, và sau một phút đọc sẽ trở lại trống?
xaifer48Nhận được, cảm ơn.
Cỏ nhỏXử lý lỗi, in tin và thử xem, làm một lỗi là được.
Khả năng định lượngVì theo quy định của Binance, thông tin chỉ được đẩy khi thông tin tài khoản thay đổi.