avatar of 发明者量化-小小梦 发明者量化-小小梦
fokus pada Pesan pribadi
4
fokus pada
1271
Pengikut

Praktik Kuantitatif Pertukaran DEX (1) -- Panduan Pengguna dYdX v4

Dibuat di: 2024-12-24 17:09:32, diperbarui pada: 2024-12-26 21:41:46
comments   0
hits   1049

[TOC]

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Kata pengantar

Dengan pesatnya perkembangan bursa terdesentralisasi (DEX) di bidang perdagangan mata uang kripto, pedagang kuantitatif secara bertahap mulai beralih ke platform ini untuk perdagangan otomatis yang efisien. Sebagai salah satu platform perdagangan terdesentralisasi yang paling populer, dYdX menyediakan fungsi perdagangan yang canggih dan mendukung perdagangan kontrak berjangka berjangka. Versi terbarunya v4 mengoptimalkan kinerja dan pengalaman pengguna, menjadikannya pilihan utama bagi banyak pedagang kuantitatif.

Artikel ini akan memperkenalkan cara mempraktikkan perdagangan kuantitatif pada dYdX v4, termasuk cara menggunakan API untuk berdagang, memperoleh data pasar, dan mengelola akun.

  • Pengujian peralihan lingkungan
  • Pertanyaan Informasi Pasar
  • Permintaan informasi pesanan dan informasi posisi
  • Tempatkan pesanan
  • Manajemen sub-akun
  • Permintaan metode simpul

dYdX v4 DEX

  • Halaman Aplikasi Testnet dYdX

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

  • DandYdX v3Begitu pula transaksi menghasilkan imbalan, imbalandYdXToken.

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Informasi koneksi dompet, login, dan konfigurasi

Pertukaran DEX protokol dYdX v3 sebelumnya telah offline. Alamat Aplikasi dYdX v4 saat ini adalah:

https://dydx.trade/trade/ETH-USD

Setelah membuka halaman Aplikasi, terdapat tombol untuk menghubungkan ke dompet di sudut kanan atas. Pindai kode QR untuk menghubungkan ke dompet.

Jika Anda ingin menguji dan membiasakan diri dengan lingkungan jaringan pengujian terlebih dahulu, Anda dapat menggunakan jaringan pengujian:

https://v4.testnet.dydx.exchange/trade/ETH-USD

Klik juga tombol hubungkan dompet di sudut kanan atas, pindai kode QR untuk menghubungkan ke dompet, dan verifikasi tanda tangan. Setelah dompet berhasil terhubung, alamat dydx v4 akan dibuat secara otomatis. Alamat ini akan ditampilkan di sudut kanan atas halaman Aplikasi. Menu akan muncul setelah mengkliknya. Ini termasuk operasi seperti pengisian ulang, penarikan, dan transfer. Salah satu perbedaan antara mainnet dYdX (lingkungan produksi) dan testnet adalah ketika Anda mengklik tombol isi ulang pada testnet, aset 300 USDC akan secara otomatis disetorkan ke faucet untuk pengujian. Jika Anda ingin melakukan transaksi nyata di dYdX, Anda perlu menyetor aset USDC. Pengisian ulang juga sangat mudah dan kompatibel dengan berbagai aset dan rantai.

  • Alamat Akun dYdX v4 Alamat akun dYdX v4 berasal dari alamat dompet. Alamat akun dYdX v4 terlihat seperti ini:dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, adalah alamat yang dimulai dengan dydx1. Alamat ini dapat ditanyakan dalam penjelajah blockchain.

  • Ilmu tentang cara menghafal Anda dapat mengekspor mnemonic akun alamat dYdX saat ini dengan mengklik tombol “Ekspor Kata Sandi” di menu sudut kanan atas. Saat menambahkan bursa pada platform FMZ, Anda perlu mengonfigurasi mnemonik ini.

Mnemonik dapat dikonfigurasikan langsung pada platform FMZ atau disimpan secara lokal pada kustodian. Saat menggunakan objek pertukaran dydx v4, konten file yang merekam mnemonik akan terbaca, yang akan ditunjukkan pada bagian praktis artikel ini.

Perbedaan antara Mainnet dan Testnet

Lingkungan testnet berbeda dari lingkungan mainnet dalam beberapa aspek. Berikut ini beberapa perbedaan sederhana.

  • Transfer aset sub-akun. Jaringan utama memiliki mekanisme pembersihan sub-akun.subAccountNumber >= 128Jika sub-akun dengan ID ini tidak memiliki posisi, aset akan secara otomatis dihapus ke sub-akun dengan subAccountNumber 0. Selama pengujian, ditemukan bahwa jaringan uji tidak memiliki mekanisme seperti itu (atau kondisi pemicunya berbeda dan belum dipicu pada jaringan uji).

  • Beberapa nama token. Token asli dydx diberi nama berbeda: MainnetDYDX, jaringan ujiDv4TNT

  • Konfigurasi alamat, seperti ID rantai, alamat node, alamat pengindeks, dll. Ada banyak node dan konfigurasi, berikut salah satunya:

    • Jaringan utama: Alamat pengindeks:https://indexer.dydx.trade ID Rantai:dydx-mainnet-1 Simpul REST:https://dydx-dao-api.polkachu.com:443

    • Jaringan uji: Alamat pengindeks:https://indexer.v4testnet.dydx.exchange ID Rantai:dydx-testnet-4 Simpul REST:https://dydx-testnet-api.polkachu.com

Arsitektur Protokol dYdX v4

Protokol dYdX v4 dikembangkan berdasarkan ekosistem kosmos. Konten terkait transaksi sistem DEX dYdX v4 terutama terdiri dari dua bagian:

  • Pengindeks yang bertanggung jawab untuk menanyakan informasi pasar, informasi akun, dll.
  • pesan pesanan blockchain dydx, pesan pembatalan pesanan, pesan transfer, dll.

Pengindeks

Layanan pengindeks menyediakan protokol REST dan Websocket.

  • Protokol REST Antarmuka protokol REST mendukung kueri informasi pasar, informasi akun, informasi posisi, informasi pesanan, dll., dan telah dienkapsulasi sebagai antarmuka API terpadu pada platform FMZ.

  • Protokol WebSocket Pada platform FMZ, Anda dapat menggunakan fungsi Dial untuk membuat koneksi Websocket dan berlangganan informasi pasar.

Perlu dicatat bahwa pengindeks dydx v4 memiliki masalah yang sama dengan bursa terpusat, yaitu, pembaruan data tidak begitu tepat waktu. Misalnya, terkadang pesanan mungkin tidak ditemukan saat melakukan kueri segera setelah melakukan pemesanan. Disarankan setelah operasi tertentu (Sleep(n)) Tunggu beberapa detik sebelum bertanya lagi.

Berikut adalah contoh penggunaan fungsi Dial untuk membuat koneksi API Websocket dan berlangganan data buku pesanan:

function dYdXIndexerWSconnManager(streamingPoint) {
    var self = {}
    self.base = streamingPoint
    self.wsThread = null

    // 订阅
    self.CreateWsThread = function (msgSubscribe) {
        self.wsThread = threading.Thread(function (streamingPoint, msgSubscribe) {
            // 订单薄
            var orderBook = null 

            // 更新订单薄
            var updateOrderbook = function(orderbook, update) {
                // 更新 bids
                if (update.bids) {
                    update.bids.forEach(([price, size]) => {
                        const priceFloat = parseFloat(price)
                        const sizeFloat = parseFloat(size)

                        if (sizeFloat === 0) {
                            // 删除价格为 price 的买单
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                        } else {
                            // 更新或新增买单
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                            orderbook.bids.push({price: price, size: size})
                            // 按价格降序排序
                            orderbook.bids.sort((a, b) => parseFloat(b.price) - parseFloat(a.price))
                        }
                    })
                }

                // 更新 asks
                if (update.asks) {
                    update.asks.forEach(([price, size]) => {
                        const priceFloat = parseFloat(price)
                        const sizeFloat = parseFloat(size)

                        if (sizeFloat === 0) {
                            // 删除价格为 price 的卖单
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                        } else {
                            // 更新或新增卖单
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                            orderbook.asks.push({price: price, size: size})
                            // 按价格升序排序
                            orderbook.asks.sort((a, b) => parseFloat(a.price) - parseFloat(b.price))
                        }
                    })
                }

                return orderbook
            }

            var conn = Dial(`${streamingPoint}|reconnect=true&payload=${JSON.stringify(msgSubscribe)}`)
            if (!conn) {
                Log("createWsThread failed.")
                return
            }
            while (true) {
                var data = conn.read()
                if (data) {
                    var msg = null                    
                    try {
                        msg = JSON.parse(data)
                        if (msg["type"] == "subscribed") {
                            orderBook = msg["contents"]
                            threading.currentThread().postMessage(orderBook)
                        } else if (msg["type"] == "channel_data") {
                            orderBook = updateOrderbook(orderBook, msg["contents"])
                            threading.currentThread().postMessage(orderBook)
                        }
                    } catch (e) {
                        Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
                    }
                }
            }
        }, streamingPoint, msgSubscribe)
    }

    // 监听
    self.Peek = function () {
        return self.wsThread.peekMessage()
    }

    return self
}

function main() {
    // real : wss://indexer.dydx.trade/v4/ws
    // simulate : wss://indexer.v4testnet.dydx.exchange/v4/ws

    var symbol = "ETH-USD"
    var manager = dYdXIndexerWSconnManager("wss://indexer.dydx.trade/v4/ws")
    manager.CreateWsThread({"type": "subscribe", "channel": "v4_orderbook", "id": symbol})

    var redCode = "#FF0000"
    var greenCode = "#006400"
    while (true) {
        var depthTbl = {type: "table", title: symbol + " / depth", cols: ["level", "price", "amount"], rows: []}
        var depth = manager.Peek()
        if (depth) {
            for (var i = 0; i < depth.asks.length; i++) {
                if (i > 9) {
                    break
                }
                var ask = depth.asks[i]
                depthTbl.rows.push(["asks " + (i + 1) + greenCode, ask.price + greenCode, ask.size + greenCode])
            }
            depthTbl.rows.reverse()

            for (var i = 0; i < depth.bids.length; i++) {
                if (i > 9) {
                    break
                }
                var bid = depth.bids[i]
                depthTbl.rows.push(["bids " + (i + 1) + redCode, bid.price + redCode, bid.size + redCode])
            }
        }
        LogStatus(_D(), "\n`" + JSON.stringify(depthTbl) + "`")
    }
}

Siaran pesan simpul rantai dYdX

Pesan yang paling umum digunakan dalam transaksi adalah pesan pesanan, pesan pembatalan pesanan, dan pesan transfer.

  • Ringkasan pesan pesanan
  {
    "@type": "/dydxprotocol.clob.MsgPlaceOrder",
    "order": {
      "orderId": {
        "subaccountId": {
          "owner": "xxx"
        },
        "clientId": xxx,
        "orderFlags": 64,
        "clobPairId": 1
      },
      "side": "SIDE_BUY",
      "quantums": "2000000",
      "subticks": "3500000000",
      "goodTilBlockTime": 1742295981
    }
  }
  • Batas Pesanan: Dalam fungsi order yang dienkapsulasi pada platform FMZ, nilai orderFlags yang digunakan untuk limit order adalah:ORDER_FLAGS_LONG_TERM = 64 # 长期订单Berdasarkan batasan protokol DYDX v4, maka digunakan masa berlaku order terpanjang, yakni 90 hari (semua jenis order pada DYDX v4 memiliki masa berlaku).

  • Pesanan Pasar: Dalam fungsi order yang dienkapsulasi pada platform FMZ, nilai orderFlags yang digunakan oleh order pasar adalah:ORDER_FLAGS_SHORT_TERM = 0 # 短期订单, sesuai dengan rekomendasi protokol DYDX v4:

    // Recommend set to oracle price - 5% or lower for SELL, oracle price + 5% for BUY

    Karena ini bukan order pasar sebenarnya, maka harga oracle digunakan, ditambah atau dikurangi 5% slippage sebagai order pasar. Pengaturan periode validitas order jangka pendek juga berbeda dengan order jangka panjang. Order jangka pendek menggunakan periode validitas tinggi blok. Berdasarkan rekomendasi dydx v4, diatur ke blok saat ini + 10 tinggi blok. sebelum kedaluwarsa.

  • ID Pesanan: Karena operasi order dilakukan langsung pada rantai, tidak akan ada ID order yang dihasilkan oleh pengindeks setelah pesan disiarkan, dan order pengindeks tidak dapat digunakan sebagai nilai balik dari fungsi order platform. Untuk memastikan keunikan dari ID pesanan dan keakuratan kueri pesanan, urutan pengindeks dikembalikan. ID pesanan terdiri dari informasi berikut (dipisahkan koma):

    • Pasangan Perdagangan
    • alamat rekening giro dydx
    • Nomor subakun (subaccountNumber)
    • clientId (dibuat secara acak)
    • clobPairId (ID simbol transaksi)
    • orderFlags
    • goodTilData (milidetik)
  • Ringkasan pesan pembatalan pesanan

  {
    "@type": "/dydxprotocol.clob.MsgCancelOrder",
    "orderId": {
      "subaccountId": {
        "owner": "xxx"
      },
      "clientId": 2585872024,
      "orderFlags": 64,
      "clobPairId": 1
    },
    "goodTilBlockTime": 1742295981
  }

ID pesanan yang dikembalikan oleh antarmuka pesanan platform FMZ perlu diteruskan.

  • Ringkasan pesan transfer
  {
    "@type": "/dydxprotocol.sending.MsgCreateTransfer",
    "transfer": {
      "sender": {
        "owner": "xxx"
      },
      "recipient": {
        "owner": "xxx",
        "number": 128
      },
      "amount": "10000000"
    }
  }

Banyak sub-akun yang dapat dibuat di bawah alamat dydx v4 saat ini. Sub-akun dengan subAccountNumber 0 adalah sub-akun pertama yang dibuat secara otomatis. ID sub-akun dengan subAccountNumber lebih besar atau sama dengan 128 digunakan untuk perdagangan posisi terisolasi, yang membutuhkan setidaknya 20 aset USDC. Misalnya, Anda dapat berpindah dari subNomorAkun 0 -> 128, atau dari subNomorAkun 128 -> 0. Transfer memerlukan konsumsi Biaya Gas. Gas Fee dapat menggunakan token USDC dan dydx.

Latihan platform FMZ dYdX v4

Konten di atas menjelaskan secara singkat beberapa detail pengemasan. Selanjutnya, mari kita praktikkan penggunaan spesifiknya. Di sini kita menggunakan jaringan uji dYdX v4 untuk demonstrasi. Jaringan uji pada dasarnya sama dengan jaringan utama, dan ada keran otomatis untuk menerima aset uji. . Penjaga menyebarkan Saya tidak akan membahas detail tentang operasinya, dan membuat uji coba sesungguhnya di FMZ.

1. Konfigurasi

Setelah berhasil terhubung ke Aplikasi dYdX v4 menggunakan dompet mata uang kripto (saya menggunakan dompet imToken di sini), klaim aset pengujian Anda, lalu ekspor mnemonic untuk akun dYdX v4 Anda saat ini (yang diambil dari dompet Anda).

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Konfigurasikan mnemonic pada platform FMZ. Di sini, kami menggunakan metode file lokal untuk mengonfigurasinya (Anda juga dapat mengisinya secara langsung dan mengonfigurasinya ke platform. Mnemonic dikonfigurasi setelah enkripsi, bukan dalam teks biasa).

  • Berkas mnemonik: mnemonic.txt

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Letakkan di direktori folder ID disk yang sebenarnya di bawah direktori kustodian. Tentu saja, ia juga dapat ditempatkan di direktori lain (jalur spesifik perlu ditulis selama konfigurasi).

  • Konfigurasikan pertukaran di FMZ

https://www.fmz.com/m/platforms/add

Isi kotak edit mnemonik:file:///mnemonic.txt, jalur sebenarnya yang sesuai adalah:托管者所在目录/logs/storage/594291

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

2. Beralih ke jaringan uji dydx v4

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // 读取账户信息测试
    Log(exchange.GetAccount()) 
}

Baca informasi akun jaringan pengujian:

{
	"Info": {
		"subaccounts": [{
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 0,
			"equity": "300.386228",
			"latestProcessedBlockHeight": "28193227",
			"freeCollateral": "300.386228",
			"openPerpetualPositions": {},
			"assetPositions": {
				"USDC": {
					"subaccountNumber": 0,
					"size": "300.386228",
					"symbol": "USDC",
					"side": "LONG",
					"assetId": "0"
				}
			},
			"marginEnabled": true,
			"updatedAtHeight": "28063818"
		}, {
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"equity": "0",
			"freeCollateral": "0",
			"openPerpetualPositions": {},
			"marginEnabled": true,
			"subaccountNumber": 1,
			"assetPositions": {},
			"updatedAtHeight": "27770289",
			"latestProcessedBlockHeight": "28193227"
		}, {
			"equity": "0",
			"openPerpetualPositions": {},
			"marginEnabled": true,
			"updatedAtHeight": "28063818",
			"latestProcessedBlockHeight": "28193227",
			"subaccountNumber": 128,
			"freeCollateral": "0",
			"assetPositions": {},
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez"
		}],
		"totalTradingRewards": "0.021744179376211564"
	},
	"Stocks": 0,
	"FrozenStocks": 0,
	"Balance": 300.386228,
	"FrozenBalance": 0,
	"Equity": 300.386228,
	"UPnL": 0
}

3. Penyelidikan informasi pasar

Tidak beralih ke jaringan uji, diuji dengan jaringan utama

function main() {
    var markets = exchange.GetMarkets()
    if (!markets) {
        throw "get markets error"
    }
    var tbl = {type: "table", title: "test markets", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: []}
    for (var symbol in markets) {
        var market = markets[symbol]
        tbl.rows.push([symbol, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal])
    }
    LogStatus("`" + JSON.stringify(tbl) +  "`")
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

4. Lakukan pemesanan

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // 限价单,挂单
    var idSell = exchange.CreateOrder("ETH_USD.swap", "sell", 4000, 0.002)
    var idBuy = exchange.CreateOrder("ETH_USD.swap", "buy", 3000, 0.003)

    // 市价单
    var idMarket = exchange.CreateOrder("ETH_USD.swap", "buy", -1, 0.01)

    Log("idSell:", idSell)
    Log("idBuy:", idBuy)
    Log("idMarket:", idMarket)
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Halaman Aplikasi dYdX v4:

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

5. Informasi pesanan

Jaringan pengujian menempatkan dua pesanan terlebih dahulu, menguji perolehan pesanan tertunda saat ini, dan membatalkan pesanan.

function main() {    
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var orders = exchange.GetOrders()
    Log("orders:", orders)
    for (var order of orders) {
        exchange.CancelOrder(order.Id, order)
        Sleep(2000)
    }

    var tbl = {type: "table", title: "test GetOrders", cols: ["Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
    for (var order of orders) {
        tbl.rows.push([order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
    }
    LogStatus("`" + JSON.stringify(tbl) +  "`")
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

6. Permintaan informasi posisi

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var p1 = exchange.GetPositions("USD.swap")
    var p2 = exchange.GetPositions("ETH_USD.swap")
    var p3 = exchange.GetPositions()
    var p4 = exchange.GetPositions("SOL_USD.swap")

    var tbls = []
    for (var positions of [p1, p2, p3, p4]) {
        var tbl = {type: "table", title: "test GetPosition/GetPositions", cols: ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], rows: []}
        for (var p of positions) {
            tbl.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
        } 
        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

7. Manajemen sub-akun

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // subAccountNumber 0 -> 128 : 20 USDC , Gas Fee 为 adv4tnt 即 dydx token
    var ret = exchange.IO("transferUSDCToSubaccount", 0, 128, "adv4tnt", 20)  
    Log("ret:", ret)

    // 切换到子账号subAccountNumber 128 ,读取账户信息检查
    exchange.IO("subAccountNumber", 128)

    var account = exchange.GetAccount()
    Log("account:", account)
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Beralih ke subakun yang subAccountNumbernya adalah 128, dan data yang dikembalikan oleh GetAccount adalah:

{
	"Info": {
		"subaccounts": [{
			"subaccountNumber": 0,
			"assetPositions": {
				"USDC": {
					"size": "245.696892",
					"symbol": "USDC",
					"side": "LONG",
					"assetId": "0",
					"subaccountNumber": 0
				}
			},
			"updatedAtHeight": "28194977",
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"freeCollateral": "279.5022142346",
			"openPerpetualPositions": {
				"ETH-USD": {
					"closedAt": null,
					"size": "0.01",
					"maxSize": "0.01",
					"exitPrice": null,
					"unrealizedPnl": "-0.17677323",
					"subaccountNumber": 0,
					"status": "OPEN",
					"createdAt": "2024-12-26T03:36:09.264Z",
					"createdAtHeight": "28194494",
					"sumClose": "0",
					"netFunding": "0",
					"market": "ETH-USD",
					"side": "LONG",
					"entryPrice": "3467.2",
					"realizedPnl": "0",
					"sumOpen": "0.01"
				}
			},
			"marginEnabled": true,
			"equity": "280.19211877"
		}, {
			"openPerpetualPositions": {},
			"assetPositions": {},
			"marginEnabled": true,
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 1,
			"equity": "0",
			"freeCollateral": "0",
			"updatedAtHeight": "27770289"
		}, {
			"openPerpetualPositions": {},
			"updatedAtHeight": "28194977",
			"latestProcessedBlockHeight": "28195008",
			"address": "dydx1fzsndj35a26maujxff88q2ge5jr4nzfeljn2ez",
			"subaccountNumber": 128,
			"assetPositions": {
				"USDC": {
					"assetId": "0",
					"subaccountNumber": 128,
					"size": "20",
					"symbol": "USDC",
					"side": "LONG"
				}
			},
			"marginEnabled": true,
			"equity": "20",
			"freeCollateral": "20"
		}],
		"totalTradingRewards": "0.021886899964446858"
	},
	"Stocks": 0,
	"FrozenStocks": 0,
	"Balance": 20,
	"FrozenBalance": 0,
	"Equity": 20,
	"UPnL": 0
}

Terlihat bahwa sub-akun dengan subAccountNumber 128 telah mentransfer 20 USDC.

8. Dapatkan TxHash dan panggil antarmuka node REST

Sesuai pesanan, dapatkan TxHash dan uji metode pemanggilan IO node REST

Bagaimana cara mendapatkan TxHash dari suatu order? Objek bursa dydx akan menyimpan TxHash, yang dapat di-query menggunakan ID order. Namun, setelah strategi berhenti, peta hash transaksi pesanan yang di-cache akan dihapus.

function main() {
    // 切换测试链的索引器地址
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // 切换测试链的ChainId 
    exchange.IO("chainId", "dydx-testnet-4")

    // 切换测试链的REST节点地址
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    var id1 = exchange.CreateOrder("ETH_USD.swap", "buy", 3000, 0.002)
    var hash1 = exchange.IO("getTxHash", id1)
    Log("id1:", id1, "hash1:", hash1)

    var id2 = exchange.CreateOrder("ETH_USD.swap", "buy", 2900, 0.003)
    var hash2 = exchange.IO("getTxHash", id2)
    Log("id2:", id2, "hash2:", hash2)
    
    // 清空映射表可以使用:exchange.IO("getTxHash", "")
    var arr = [hash1, hash2]
    
    Sleep(10000)
    for (var txHash of arr) {
        // GET https://docs.cosmos.network   /cosmos/tx/v1beta1/txs/{hash}
        var ret = exchange.IO("api", "GET", "/cosmos/tx/v1beta1/txs/" + txHash)
        Log("ret:", ret)
    }
}

Praktik Kuantitatif Pertukaran DEX (1) – Panduan Pengguna dYdX v4

Pesan yang ditanyakan melalui TxHash:

var ret = exchange.IO(“api”, “GET”, “/cosmos/tx/v1beta1/txs/” + txHash)

Kontennya terlalu panjang, berikut beberapa kutipan untuk demonstrasi:

{
	"tx_response": {
		"codespace": "",
		"code": 0,
		"logs": [],
		"info": "",
		"height": "28195603",
		"data": "xxx",
		"raw_log": "",
		"gas_wanted": "-1",
		"gas_used": "0",
		"tx": {
			"@type": "/cosmos.tx.v1beta1.Tx",
			"body": {
				"messages": [{
					"@type": "/dydxprotocol.clob.MsgPlaceOrder",
					"order": {
						"good_til_block_time": 1742961542,
						"condition_type": "CONDITION_TYPE_UNSPECIFIED",
						"order_id": {
							"clob_pair_id": 1,
							"subaccount_id": {
								"owner": "xxx",
								"number": 0
							},
							"client_id": 2999181974,
							"order_flags": 64
						},
						"side": "SIDE_BUY",
						"quantums": "3000000",
						"client_metadata": 0,
						"conditional_order_trigger_subticks": "0",
						"subticks": "2900000000",
						"time_in_force": "TIME_IN_FORCE_UNSPECIFIED",
						"reduce_only": false
					}
				}],
				"memo": "FMZ",
				"timeout_height": "0",
				"extension_options": [],
				"non_critical_extension_options": []
			},
      ...

THE END

Pengujian di atas didasarkan pada kustodian terbaru. Anda perlu mengunduh kustodian terbaru untuk mendukung dYdX v4 DEX

Terima kasih atas dukungan Anda dan terima kasih telah membaca.