avatar of 发明者量化-小小梦 发明者量化-小小梦
tập trung vào tin nhắn riêng tư
4
tập trung vào
1271
Người theo dõi

Thiết kế và triển khai giám sát chênh lệch giá sàn giao dịch DEX-CEX dựa trên định lượng FMZ

Được tạo ra trong: 2025-02-21 10:40:52, cập nhật trên: 2025-02-21 13:53:00
comments   0
hits   1232

Thiết kế và triển khai giám sát chênh lệch giá sàn giao dịch DEX-CEX dựa trên định lượng FMZ

Một số sàn giao dịch DEX, bao gồm dydx_v4, hyperliquid, vertex và aevo, đã được đóng gói và kết nối trên FMZ. Khi cuộc cạnh tranh về chênh lệch giá trong các sàn giao dịch tập trung ngày càng trở nên khốc liệt, nhiều nhà giao dịch định lượng đã chuyển sự chú ý của họ sang các sàn giao dịch phi tập trung. Trong bài viết này, chúng tôi sẽ thảo luận về thiết kế và triển khai giám sát chênh lệch giá giữa DEX và CEX.

Bước đầu tiên của chiến lược phòng ngừa rủi ro chênh lệch giá là tính toán chênh lệch giá của danh mục đầu tư mục tiêu và quan sát, phân tích xem có bất kỳ cơ hội giao dịch nào không. Do đó, thiết kế và triển khai chiến lược giám sát chênh lệch giá là nhiệm vụ cơ bản đầu tiên. Các yêu cầu thiết kế của chúng tôi là:

  • Ngôn ngữ lập trình được sử dụng là Javascript.
  • Sử dụng giao diện REST được đóng gói.
  • Lựa chọn DEX: siêu thanh khoản, đỉnh.
  • Lựa chọn CEX: binance, bybit.
  • Yêu cầu dữ liệu sổ lệnh sử dụng các yêu cầu đồng thời đa luồng.
  • Các sản phẩm thử nghiệm phải là các sản phẩm chính thống được chia sẻ bởi tất cả các sàn giao dịch càng nhiều càng tốt: ETH, cặp giao dịch giao ngay BTC/hợp đồng vĩnh viễn
  • Cố gắng đơn giản hóa thiết kế và cung cấp triển khai cơ bản bằng cách sử dụng mã đơn giản và dễ hiểu.

Triển khai mã

Mã này có ít hơn 200 dòng và chức năng được thiết kế chỉ là tính toán chênh lệch giá theo thời gian thực của một sản phẩm nhất định trên các sàn giao dịch khác nhau. Khi chiến lược được chạy lần đầu, tất cả các đối tượng trao đổi được cấu hình cho chiến lược sẽ được phân loại thành nhóm DEX và nhóm CEX. Mỗi cuộc thăm dò được thực hiện thông qua chức năng đa luồng Thread được đóng gói bởi nền tảng FMZ và đồng thời yêu cầu giao diện REST: giao diện sổ lệnhGetDepth, ghi lại danh sách lệnh mua và dữ liệu danh sách lệnh bán theo yêu cầu của các loại hàng hóa cần thiết. Sau đó, nhóm DEX và nhóm CEX được kết hợp thành một tổ hợp chênh lệch (tổ hợp DEX-CEX, tức là cặp chênh lệch giá) và tính toán chênh lệch giá.

Xác định loại trao đổi: Trong quá trình khởi tạo, đối tượng trao đổi được thêm vào sẽ được đánh giá để xác định xem đó là giao ngay hay tương lai.

Các sàn giao dịch khác nhau có thể có tên gọi khác nhau cho một tài sản cơ bản nhất định, do đó tên của sản phẩm cần được điều chỉnh: Chương trình cần được điều chỉnh theo quy tắc đặt tên ký hiệu của các sàn giao dịch khác nhau. Ví dụ, các cặp giao dịch của hợp đồng Vertex được đặt tên như sau:XXX_USD, thực chất là hợp đồng vĩnh viễn dựa trên USDC. Tên của ETH trong vị trí của Vertex là WETH.

Có được độ chính xác: Trong quá trình khởi tạo, toàn bộ thông tin thị trường được thu thập. Theo ký hiệu cụ thể được yêu cầu, độ chính xác tương ứng có thể được truy vấn cho các hoạt động xử lý độ chính xác dữ liệu tiếp theo.

Yêu cầu dữ liệu Trước khi thu thập được toàn bộ dữ liệu độ sâu, chương trình sẽ đợi và tiếp tục kiểm tra xem có sàn giao dịch nào có dữ liệu chưa được cập nhật hay không. Nếu dữ liệu chưa được lấy, chương trình sẽ chuyển sang chế độ ngủ trong 100 mili giây. Dữ liệu sổ lệnh được yêu cầu sẽ được ghi lại trong một đối tượng được tạo bởi threading.Dict() (được sử dụng để tương tác với các luồng đồng thời) và dữ liệu sẽ được đặt lại vào cuối mỗi cuộc thăm dò.

Tóm tắt Việc triển khai chiến lược này cho thấy cách theo dõi sự chênh lệch giá giữa nhiều sàn giao dịch theo thời gian thực và tính toán các cơ hội kinh doanh chênh lệch giá có thể xảy ra. Thông qua việc hiệu chỉnh ký hiệu hợp lý, thu thập dữ liệu sâu, kiểm soát chính xác và hoạt động đa luồng, hệ thống có thể theo dõi hiệu quả sự chênh lệch giá theo thời gian thực. Đối với người học chiến lược, việc hiểu các ý tưởng triển khai của mã này có thể giúp họ nắm vững cách sử dụng API để lấy dữ liệu giao dịch, cách xử lý dữ liệu từ nhiều sàn giao dịch, cách tính toán và đưa ra mức chênh lệch giao dịch và cách áp dụng các công nghệ này vào các giao dịch thực tế.

let symbolList = []

function createEx(idx, exs) {
    let self = {}
    
    let cexEidList = ["Binance", "Bybit", "Futures_Binance", "Futures_Bybit"]
    let dexEidList = ["Vertex", "Hyperliquid", "Futures_Hyperliquid", "Futures_Vertex"]

    self.name = exs[idx].GetName()
    self.idx = idx
    self.e = exs[idx]
    self.depths = threading.Dict()
    self.markets = self.e.GetMarkets()

    if (!self.markets) {
        throw "GetMarkets error"
    }

    if (dexEidList.includes(self.name)) {
        self.type = "DEX"
    } else if (cexEidList.includes(self.name)) {
        self.type = "CEX"
    } else {
        throw "not support " + self.name
    }

    if (self.name.startsWith("Futures_")) {
        self.isFutures = true
    } else {
        self.isFutures = false
    }

    self.correctSymbol = function(symbol) {        
        if (self.name == "Vertex") {
            let correctList = {"BTC_USDC": "WBTC_USDC", "ETH_USDC": "WETH_USDC"}
            if (typeof(correctList[symbol]) != "undefined") {
                return correctList[symbol]
            }
        } else if (self.name == "Hyperliquid") {
            let correctList = {"BTC_USDC": "UBTC_USDC"}
            if (typeof(correctList[symbol]) != "undefined") {
                return correctList[symbol]
            }
        } else if (self.name == "Futures_Hyperliquid") {
            return symbol.replace("_USDC", "_USD")
        }
        
        return symbol
    }

    self.reqDepth = function(symbol) {
        symbol = self.correctSymbol(symbol)
        threading.Thread(function(idx, symbol, threadingDict) {
            let depth = exchanges[idx].GetDepth(symbol)
            if (depth) {
                threadingDict.set(symbol, depth)
            } else {
                threadingDict.set(symbol, null)
            }
        }, self.idx, symbol, self.depths)
    }
    
    self.getPrecision = function(symbol) {
        symbol = self.correctSymbol(symbol)
        let marketInfo = self.markets[symbol]
        if (marketInfo) {
            return [marketInfo.PricePrecision, marketInfo.AmountPrecision]
        } else {
            return [8, 8]
        }
    }

    self.init = function() {
        self.depths = threading.Dict()
    }

    self.getDepth = function(symbol) {
        symbol = self.correctSymbol(symbol)
        return self.depths.get(symbol)
    }

    return self
}

function createManager(symbolList, exs) {
    let self = {}

    self.symbolList = symbolList
    self.exchanges = []
    self.hedgePair = []

    self.initHedgePair = function () {
        for (let i in exs) {
            let ex = createEx(i, exs)
            self.exchanges.push(ex)
        }

        let arrDEX = self.exchanges.filter(item => item.type == "DEX")
        let arrCEX = self.exchanges.filter(item => item.type == "CEX")

        for (let dex of arrDEX) {
            for (let cex of arrCEX) {
                self.hedgePair.push({"dex": dex, "cex": cex})
            }
        }
    }

    self.calcHedgeData = function () {
        let beginTimestamp = new Date().getTime()
        for (let e of self.exchanges) {
            for (let symbol of self.symbolList) {
                e.reqDepth(symbol)
            }
        }

        while (true) {
            let isWait = false
            for (let e of self.exchanges) {
                for (let symbol of self.symbolList) {
                    let depth = e.getDepth(symbol)
                    if (depth == null || typeof(depth) == "undefined") {
                        isWait = true
                    }
                }
            }
            if (isWait) {
                Sleep(100)
            } else {
                break
            }
        }

        let tbls = []
        for (let symbol of self.symbolList) {
            let tbl = {"type": "table", "title": symbol + "差价", "cols": ["pair", "bid-ask", "ask-bid", "dex ask", "dex bid", "cex ask", "cex bid"], "rows": []}
            for (let p of self.hedgePair) {
                let dex = p["dex"]
                let cex = p["cex"]

                let pricePrecision = Math.max(dex.getPrecision(symbol)[0], cex.getPrecision(symbol)[0])

                let dexDepth = dex.getDepth(symbol)
                let cexDepth = cex.getDepth(symbol)
                if (dexDepth && cexDepth) {
                    p["bid-ask"] = _N(dexDepth.Bids[0].Price - cexDepth.Asks[0].Price, pricePrecision)
                    p["ask-bid"] = _N(dexDepth.Asks[0].Price - cexDepth.Bids[0].Price, pricePrecision)

                    // 输出信息、观察测试
                    Log(dex.name, cex.name, symbol, "bid-ask:", p["bid-ask"], ", ask-bid", p["ask-bid"])

                    p[dex.name + "-ask"] = dexDepth.Asks[0].Price + "/" + dexDepth.Asks[0].Amount
                    p[dex.name + "-bid"] = dexDepth.Bids[0].Price + "/" + dexDepth.Bids[0].Amount
                    p[cex.name + "-ask"] = cexDepth.Asks[0].Price + "/" + cexDepth.Asks[0].Amount
                    p[cex.name + "-bid"] = cexDepth.Bids[0].Price + "/" + cexDepth.Bids[0].Amount
                } else {
                    p["bid-ask"] = "--"
                    p["ask-bid"] = "--"
                    p[dex.name + "-ask"] = "--"
                    p[dex.name + "-bid"] = "--"
                    p[cex.name + "-ask"] = "--"
                    p[cex.name + "-bid"] = "--"
                }

                let pairName = dex.name + "-" + cex.name
                tbl["rows"].push([pairName, p["bid-ask"], p["ask-bid"], p[dex.name + "-ask"], p[dex.name + "-bid"], p[cex.name + "-ask"], p[cex.name + "-bid"]])
            }
            tbls.push(tbl)
        }
                
        for (let e of self.exchanges) {
            e.init()
        }

        let endTimestamp = new Date().getTime()
        return [tbls, (endTimestamp - beginTimestamp) + "毫秒"]
    }

    self.initHedgePair()
    return self
}

function main() {
    LogReset(1)
    let loopCount = 0

    symbolList = strSymbolList.split(",")
    let m = createManager(symbolList, exchanges)
    while (true) {
        let ret = m.calcHedgeData()
        loopCount++
        LogStatus(_D(), "耗时:", ret[1], ", 轮询次数:", loopCount, "\n", "`" + JSON.stringify(ret[0]) + "`")
        Sleep(1000)
    }
}

Thiết kế tham số:

Thiết kế và triển khai giám sát chênh lệch giá sàn giao dịch DEX-CEX dựa trên định lượng FMZ

Thị trường giao ngay

Theo dõi một sản phẩm tại chỗ:

  • BTC_USDC Bitcoin sang USDC giao ngay

Thiết kế và triển khai giám sát chênh lệch giá sàn giao dịch DEX-CEX dựa trên định lượng FMZ

Thị trường hợp đồng

Theo dõi hai giống:

  • ETH_USDC.swap Hợp đồng vĩnh viễn Ethereum
  • BTC_USDC.swap Hợp đồng vĩnh viễn Bitcoin

Thiết kế và triển khai giám sát chênh lệch giá sàn giao dịch DEX-CEX dựa trên định lượng FMZ

END

Hướng mở rộng:

  • Giám sát ngưỡng và đóng gói logic giao dịch.
  • Tính toán các loại phí và chi phí, đồng thời tính toán phạm vi chênh lệch phòng ngừa rủi ro hợp lý.
  • Sử dụng giao diện websocket để lấy dữ liệu thị trường.

Nền tảng FMZ sẽ tiếp tục tăng cường hỗ trợ kỹ thuật cho các sàn giao dịch phi tập trung (DEX) và tài chính phi tập trung (DeFi), đồng thời liên tục lặp lại và cập nhật các chức năng và sản phẩm.

Cảm ơn các bạn đã đọc.