
Beberapa pertukaran DEX, termasuk dydx_v4, hyperliquid, vertex, dan aevo, telah dikapsulkan dan disambungkan pada FMZ Memandangkan persaingan untuk arbitraj harga dalam pertukaran berpusat menjadi semakin sengit, ramai pedagang kuantitatif telah mengalihkan perhatian mereka kepada pertukaran terdesentralisasi Dalam artikel ini, kita akan membincangkan reka bentuk dan pelaksanaan DEX.
Langkah pertama strategi arbitraj lindung nilai adalah untuk mengira perbezaan harga portfolio sasaran dan memerhati dan menganalisis sama ada terdapat sebarang peluang perdagangan. Oleh itu, mereka bentuk dan melaksanakan strategi pemantauan perbezaan harga ialah tugas asas pertama kami ialah:
Kod ini kurang daripada 200 baris, dan fungsi reka bentuknya hanya untuk mengira perbezaan harga masa nyata produk tertentu dalam pertukaran yang berbeza. Apabila strategi dijalankan pada mulanya, semua objek pertukaran yang dikonfigurasikan untuk strategi akan diklasifikasikan ke dalam kumpulan DEX dan kumpulan CEX. Setiap tinjauan pendapat dilakukan melalui fungsi berbilang benang Benang yang dikapsulkan oleh platform FMZ, dan serentak meminta antara muka REST: antara muka buku pesananGetDepth, merekodkan senarai pesanan beli yang diminta dan data senarai pesanan jual bagi jenis yang diperlukan. Kemudian, kumpulan DEX dan kumpulan CEX digabungkan menjadi gabungan perbezaan (kombinasi DEX-CEX, iaitu pasangan arbitraj), dan perbezaan harga dikira.
Penentuan jenis pertukaran: Semasa permulaan, objek pertukaran tambahan akan dinilai untuk menentukan sama ada ia adalah spot atau niaga hadapan.
Pertukaran yang berbeza mungkin mempunyai nama yang berbeza untuk aset asas tertentu, jadi nama produk perlu dilaraskan:
Program ini perlu diselaraskan mengikut peraturan penamaan simbol pertukaran yang berbeza. Sebagai contoh, pasangan dagangan kontrak Vertex dinamakan seperti berikut:XXX_USD, yang sebenarnya merupakan kontrak kekal berdasarkan USDC. Nama ETH di tempat Vertex ialah WETH.
Dapatkan ketepatan: Semasa pemulaan, keseluruhan maklumat pasaran diperolehi Menurut simbol khusus yang diminta, ketepatan yang sepadan boleh ditanya untuk operasi pemprosesan ketepatan data yang berikutnya.
Permintaan Data Sebelum semua data kedalaman diperoleh, program akan menunggu dan terus menyemak sama ada terdapat pertukaran yang datanya belum dikemas kini. Jika data belum diperoleh, program akan tidur selama 100 milisaat. Data buku pesanan yang diminta direkodkan dalam objek yang dibuat oleh threading.Dict() (digunakan untuk interaksi dengan urutan serentak) dan data ditetapkan semula pada penghujung setiap tinjauan pendapat.
ringkaskan Pelaksanaan strategi ini menunjukkan cara memantau perbezaan harga merentas berbilang bursa dalam masa nyata dan mengira kemungkinan peluang arbitraj. Melalui pembetulan simbol yang munasabah, penangkapan data dalam, kawalan ketepatan dan operasi berbilang benang, sistem boleh memantau perbezaan harga masa nyata dengan cekap. Bagi pelajar strategi, memahami idea pelaksanaan kod ini boleh membantu mereka menguasai cara menggunakan API untuk mendapatkan data transaksi, cara memproses data daripada berbilang bursa, cara mengira dan mengeluarkan sebaran transaksi dan cara menggunakan teknologi ini dalam urus niaga sebenar.
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)
}
}
Reka bentuk parameter:

Pantau produk spot:

Pantau dua jenis:

Arah pengembangan:
Platform FMZ akan terus meningkatkan sokongan teknikalnya untuk pertukaran terdesentralisasi (DEX) dan kewangan terdesentralisasi (DeFi), dan terus mengulang serta mengemas kini fungsi dan produk.
Terima kasih kerana membaca.