Hướng dẫn sử dụng FMZ Cryptocurrency Quantitative Platform WebSocket (Sự giải thích chi tiết về chức năng quay số nâng cấp)

Tác giả:Lydia., Tạo: 2023-07-13 14:03:32, Cập nhật: 2024-01-03 21:05:36

img

Hướng dẫn sử dụng FMZ Cryptocurrency Quantitative Platform WebSocket (Sự giải thích chi tiết về chức năng quay số nâng cấp)

Hầu hết các sàn giao dịch tiền điện tử hỗ trợ gửi dữ liệu thị trường qua WebSocket, và một số sàn giao dịch cũng hỗ trợ cập nhật thông tin tài khoản qua WebSocket. So với REST API, WebSocket thường có độ trễ thấp hơn, tần số cao hơn và không phải chịu giới hạn tốc độ API nghỉ của nền tảng. Tuy nhiên, nó có nhược điểm của sự gián đoạn tiềm ẩn và xử lý ít trực quan hơn.

Bài viết này chủ yếu giới thiệu việc sử dụng chức năng Dial, được đóng gói trong nền tảng FMZ Quant sử dụng ngôn ngữ JavaScript. Các hướng dẫn và tham số cụ thể có thể được tìm thấy trong tài liệu bằng cách tìm kiếm Dial. Để đạt được các chức năng khác nhau, chức năng Dial đã trải qua một số cập nhật, sẽ được đề cập trong bài viết này. Ngoài ra, nó cũng sẽ thảo luận về chiến lược dựa trên sự kiện dựa trên WebSocket Secure (wss) và vấn đề kết nối với nhiều sàn giao dịch.

Kết nối Websocket:

Một kết nối trực tiếp thường là đủ, chẳng hạn như nhận được một xu bảo mật ticker push:

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

Khi dữ liệu được trả về ở định dạng nén, nó cần phải được chỉ định trong quá trình kết nối. compress được sử dụng để chỉ định định dạng nén, và mode đại diện cho phần nào của dữ liệu (gửi hoặc trả lại) cần phải được nén. Ví dụ: khi kết nối với OKEX, có thể sử dụng:

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

Chức năng Dial hỗ trợ kết nối lại, được xử lý bởi ngôn ngữ Go cơ bản. Nó tự động kết nối lại khi kết nối được phát hiện bị ngắt kết nối. Đối với trường hợp dữ liệu yêu cầu đã được bao gồm trong URL, chẳng hạn như ví dụ trước đây với Binance, nó rất thuận tiện và được khuyến cáo sử dụng. Tuy nhiên, đối với trường hợp cần gửi tin nhắn đăng ký, nên duy trì cơ chế kết nối lại bằng tay.

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

Đăng ký cho các tin nhắn wss, một số sàn giao dịch có yêu cầu trong url, và cũng có các kênh mà bạn cần phải gửi đăng ký của riêng bạn, 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"]}')

2. Websocket đọc

Nói chung, nó có thể được đọc liên tục trong một vòng lặp vô hạn.

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 
    }
}

Tốc độ đẩy dữ liệu wss rất nhanh. Lớp dưới của Golang sẽ lưu trữ tất cả dữ liệu trong hàng đợi, và khi các cuộc gọi của chương trình được đọc, dữ liệu sẽ được trả về. Tuy nhiên, các hoạt động như đặt lệnh trên bot sẽ gây chậm trễ, có thể dẫn đến sự tích lũy dữ liệu. Đối với thông tin như đẩy thực thi giao dịch, đẩy tài khoản và đẩy can thiệp chiều sâu, chúng tôi cần dữ liệu lịch sử. Đối với dữ liệu thị trường báo giá, trong hầu hết các trường hợp, chúng tôi chỉ quan tâm đến dữ liệu mới nhất, không phải dữ liệu lịch sử.

Nếu read() không thêm các tham số, nó sẽ trả về dữ liệu cũ nhất, và chặn cho đến khi trả về khi không có dữ liệu. Nếu bạn 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 khi không có dữ liệu, nó sẽ trả về null, cần phải được đánh giá trước khi tham chiếu.

Tùy thuộc vào cách xử lý dữ liệu lưu trữ tạm thời cũ và liệu nó có bị chặn khi không có dữ liệu, read có các tham số khác nhau, như được hiển thị trong bảng bên dưới, trông phức tạp, nhưng làm cho chương trình linh hoạt hơn.

img

3. Kết nối với nhiều nền tảng bằng Websocket

Trong trường hợp này, rõ ràng rằng chỉ cần sử dụng read() không hoạt động trong chương trình, bởi vì một nền tảng sẽ chặn các tin nhắn đang chờ, và nền tảng khác sẽ không nhận ngay cả khi có tin nhắn 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) // 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. Các vấn đề cắt và kết nối lại

Phần này của quá trình xử lý khó khăn hơn, bởi vì dữ liệu đẩy có thể bị gián đoạn, hoặc thời gian trì hoãn đẩy cực kỳ dài. Ngay cả khi nhịp tim có thể được nhận, điều đó không có nghĩa là dữ liệu vẫn đang được đẩy. Bạn có thể đặt khoảng thời gian sự kiện; nếu không nhận được cập nhật sau khoảng thời gian, kết nối lại; tốt nhất là so sánh kết quả được trả về bởi rest sau một khoảng thời gian, để xem liệu dữ liệu có chính xác hay không. Đối với các trường hợp đặc biệt của Binance, bạn có thể trực tiếp thiết lập kết nối lại tự động.

5. Sử dụng khung chương trình chung của Websocket

Đối với dữ liệu đẩy đã được sử dụng, chương trình sẽ tự nhiên được viết như sự kiện kích hoạt; chú ý đến tần suất đẩy dữ liệu, bởi vì các yêu cầu tần số cao sẽ dẫn đến việc bị chặn; nói chung bạn có thể viết:

    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. Kết luận

Phương pháp kết nối, phương pháp truyền dữ liệu, nội dung đăng ký và định dạng dữ liệu của websocket trên mỗi nền tảng thường khác nhau, vì vậy nền tảng không đóng gói nó và cần sử dụng chức năng Dial để kết nối một mình.

PS: Mặc dù một số nền tảng không cung cấp trích dẫn websocket, trên thực tế, khi bạn đăng nhập vào trang web để sử dụng chức năng gỡ lỗi, bạn sẽ thấy rằng tất cả chúng đều sử dụng websocket push. Sau khi nghiên cứu, bạn sẽ thấy rằng một số định dạng đăng ký và định dạng trả về dường như được mã hóa, có thể được nhìn thấy bằng cách giải mã và giải nén với base64.


Thêm nữa