Sumber dimuat naik... memuat...

Amalan Kuantitatif Bursa DEX (1) -- Panduan Pengguna dYdX v4

Penulis:FMZ~Lydia, Dicipta: 2024-12-26 15:32:24, Dikemas kini: 2024-12-26 17:36:31

Pengantar

Dengan peningkatan pertukaran terdesentralisasi (DEX) yang pesat dalam bidang perdagangan mata wang kripto, pedagang kuantitatif telah beralih kepada platform ini secara beransur-ansur untuk perdagangan automatik yang cekap. Sebagai salah satu platform perdagangan terdesentralisasi yang paling popular, dYdX menyediakan fungsi perdagangan yang kuat dan menyokong perdagangan kontrak kekal niaga hadapan. Versi terbarunya v4 mengoptimumkan prestasi dan pengalaman pengguna, menjadikannya pilihan pertama bagi banyak pedagang kuantitatif.

Artikel ini akan memperkenalkan cara mengamalkan perdagangan kuantitatif di dYdX v4, termasuk cara menggunakan API untuk berdagang, mendapatkan data pasaran, dan menguruskan akaun.

  • Pertukaran persekitaran ujian
  • Permintaan maklumat pasaran
  • Permintaan maklumat pesanan dan maklumat kedudukan
  • Buat pesanan
  • Pengurusan Sub-Akaun
  • Permintaan kaedah nod

dYdX v4 DEX

  • DYdX testnet App Page

img

  • SebagaidYdX v3Dengan Ethereum, perdagangan menjana ganjaran, yang merupakan ganjarandYdX tokens.

Sambungan dompet, log masuk, dan maklumat konfigurasi

Pertukaran DEX protokol dYdX v3 sebelum ini telah di luar talian. Alamat aplikasi dYdX v4 semasa adalah:

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

Selepas membuka halaman Aplikasi, terdapat butang untuk menyambung ke dompet di sudut kanan atas. Imbas kod QR untuk menyambung ke dompet.

Jika anda ingin menguji dan membiasakan diri dengan persekitaran rangkaian ujian terlebih dahulu, anda boleh menggunakan rangkaian ujian:

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

Selain itu, klik butang menyambung dompet di sudut kanan atas, imbas kod untuk menyambung dompet, dan mengesahkan tandatangan. Selepas dompet disambungkan dengan berjaya, alamat dydx v4 akan dijana secara automatik. Alamat ini akan dipaparkan di sudut kanan atas halaman Aplikasi. Kliknya dan menu akan muncul. Terdapat operasi seperti pengecasan, pengeluaran, dan pemindahan. Salah satu perbezaan antara dYdX mainnet (lingkungan pengeluaran) dan testnet adalah apabila anda mengklik pengecasan di testnet, aset 300 USDC akan dikenakan secara automatik menggunakan keran untuk ujian. Jika anda ingin melakukan transaksi sebenar di dYdX, anda perlu mengenakan aset USDC. Pengisian semula juga sangat mudah dan serasi dengan pelbagai aset dan rantaian untuk pengecasan semula.

  • Alamat akaun dYdX v4 Alamat akaun dYdX v4 berasal dari alamat dompet. Alamat akaun dYdX v4 kelihatan seperti:dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, yang merupakan alamat yang bermula dengan dydx1. Alamat ini boleh ditanyakan dalam penjelajah blockchain.

  • Mnemonik Anda boleh menggunakan butang Export Password di menu sudut kanan atas untuk mengeksport mnemonik akaun alamat dYdX semasa. Apabila menambah pertukaran di platform FMZ, anda perlu mengkonfigurasi mnemonik ini.

Mnemonics boleh dikonfigurasi secara langsung di platform FMZ atau disimpan secara tempatan di docker. Apabila menggunakan objek pertukaran dydx v4, kandungan fail yang merakam mnemonics akan dibaca, yang akan ditunjukkan dalam bahagian praktikal artikel ini.

Perbezaan antara Mainnet dan Testnet

Kawasan testnet berbeza dengan persekitaran mainnet dalam beberapa aspek.

  • Pemindahan aset ke sub akaun. Rangkaian utama mempunyai mekanisme pembersihan sub-akaun.subAccountNumber >= 128, jika sub- akaun ID tidak mempunyai kedudukan, aset akan dibasmi secara automatik ke sub- akaun yang subAccountNumber adalah 0. Semasa ujian, didapati bahawa rangkaian ujian tidak mempunyai mekanisme ini (atau keadaan pencetus berbeza dan ia tidak dicetuskan dalam rangkaian ujian).
  • Nama-nama tertentu. Token asli dydx mempunyai nama yang berbeza: mainnetDYDX, testnetDv4TNT
  • Konfigurasi alamat, seperti ID rantaian, alamat nod, alamat penanda, dll. Terdapat banyak nod dan konfigurasi, di sini adalah salah satu daripada mereka:

Rangkaian utama: Alamat penanda:https://indexer.dydx.tradeID rantaian:dydx-mainnet-1REST Node:https://dydx-dao-api.polkachu.com:443

Rangkaian ujian: Alamat penanda:https://indexer.v4testnet.dydx.exchangeID rantaian:dydx-testnet-4REST Node:https://dydx-testnet-api.polkachu.com

Arkitektur Protokol dYdX v4

Protokol dYdX v4 dibangunkan berdasarkan ekosistem kosmos.

  • Indexer yang bertanggungjawab untuk menyoal maklumat ticker, maklumat akaun, dll.
  • mesej pesanan dydx blockchain, mesej pembatalan pesanan, mesej pemindahan, dll.

Pengindeks

Perkhidmatan pengindeksan menyediakan protokol REST dan Websocket.

  • Protokol REST Antara muka protokol REST menyokong pertanyaan maklumat pasaran, maklumat akaun, maklumat kedudukan, maklumat pesanan dan pertanyaan lain, dan telah disusun sebagai antara muka API bersatu pada platform FMZ.

  • Protokol WebSocket Pada platform FMZ, anda boleh menggunakan fungsi Dial untuk membuat sambungan Websocket dan melanggan maklumat pasaran.

Perlu diperhatikan bahawa indexer dydx v4 mempunyai masalah yang sama seperti pertukaran terpusat, iaitu, kemas kini data tidak begitu tepat pada masanya.Sleep(n)) operasi tertentu sebelum membuat pertanyaan.

Berikut adalah contoh menggunakan fungsi Dial untuk membuat sambungan Websocket API dan melanggan data buku pesanan:

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

    // subscription
    self.CreateWsThread = function (msgSubscribe) {
        self.wsThread = threading.Thread(function (streamingPoint, msgSubscribe) {
            // Order book
            var orderBook = null 

            // Update order book
            var updateOrderbook = function(orderbook, update) {
                // Update bids
                if (update.bids) {
                    update.bids.forEach(([price, size]) => {
                        const priceFloat = parseFloat(price)
                        const sizeFloat = parseFloat(size)

                        if (sizeFloat === 0) {
                            // Delete the buy order with price
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                        } else {
                            // Update or add a buy order
                            orderbook.bids = orderbook.bids.filter(bid => parseFloat(bid.price) !== priceFloat)
                            orderbook.bids.push({price: price, size: size})
                            // Sort by price descending
                            orderbook.bids.sort((a, b) => parseFloat(b.price) - parseFloat(a.price))
                        }
                    })
                }

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

                        if (sizeFloat === 0) {
                            // Delete the sell order with price
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                        } else {
                            // Update or add a sell order
                            orderbook.asks = orderbook.asks.filter(ask => parseFloat(ask.price) !== priceFloat)
                            orderbook.asks.push({price: price, size: size})
                            // Sort by price ascending
                            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)
    }

    // monitor
    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 mesej dYdX Chain Node

Mesej yang paling biasa digunakan dalam transaksi adalah mesej pesanan, mesej pembatalan pesanan, dan mesej pemindahan.

  • Ringkasan mesej 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
  }
}
  • Perintah had: Dalam fungsi pesanan yang dikemas dalam platform FMZ, nilai orderFlags yang digunakan untuk pesanan had ialah:ORDER_FLAGS_LONG_TERM = 64 # Long-term orderMenurut batasan protokol dydx v4, tempoh sah pesanan terpanjang digunakan, iaitu 90 hari (semua jenis pesanan pada dydx v4 mempunyai tempoh sah).

  • Perintah pasaran: Dalam fungsi pesanan yang dikemas dalam platform FMZ, nilai orderFlags yang digunakan untuk pesanan pasaran adalah:ORDER_FLAGS_SHORT_TERM = 0 # Short-term order, mengikut cadangan protokol dydx v4:

// mengesyorkan ditetapkan kepada harga oracle - 5% atau lebih rendah untuk menjual, harga oracle + 5% untuk membeli

Oleh kerana ini bukan pesanan pasaran yang sebenar, harga oracle digunakan, ditambah atau dikurangkan 5% slippage sebagai pesanan pasaran. Tempoh kelayakan pesanan jangka pendek juga berbeza dengan pesanan jangka panjang. Perintah jangka pendek menggunakan tempoh kelayakan ketinggian blok, yang ditetapkan pada blok semasa + 10 ketinggian blok mengikut cadangan dydx v4.

  • ID pesanan: Oleh kerana operasi pesanan dilakukan secara langsung pada rantaian, tidak akan ada ID pesanan yang dihasilkan oleh penindek selepas mesej disiarkan, dan perintah penindek tidak boleh digunakan sebagai nilai pulangan fungsi pesanan platform. Untuk memastikan keunikan ID pesanan dan ketepatan pertanyaan pesanan, ID pesanan yang dikembalikan terdiri daripada maklumat berikut (dipisahkan dengan koma):

Pasangan Dagangan alamat akaun semasa dydx Nombor sub akaun (sub akaunNombor) clientId (dijana secara rawak) clobPairId (ID simbol transaksi) PerintahBendera goodTilData (milisaat)

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

ID pesanan yang dikembalikan oleh antara muka pesanan platform FMZ perlu dihantar.

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

Banyak sub-akaun boleh dicipta di bawah alamat dydx v4 semasa. Sub-akaun dengan subAccountNumber 0 adalah sub-akaun pertama yang dicipta secara automatik. ID sub-akaun dengan subAccountNumber lebih besar daripada atau sama dengan 128 digunakan untuk perdagangan kedudukan yang terpencil, yang memerlukan sekurang-kurangnya 20 aset USDC. Sebagai contoh, anda boleh pergi dari subAccountNumber 0 -> 128, atau dari subAccountNumber 128 -> 0. Pemindahan memerlukan Bayaran Gas. Bayaran Gas boleh USDC atau token dydx.

FMZ Platform dYdX v4 Latihan

Kandungan di atas menjelaskan beberapa butiran pembungkusan secara ringkas. Seterusnya, mari kita berlatih penggunaan tertentu. Di sini kita menggunakan rangkaian ujian dYdX v4 untuk demonstrasi. Rangkaian ujian pada dasarnya sama dengan rangkaian utama, dan terdapat keran automatik untuk menerima aset ujian. Operasi penggunaan docker tidak akan diulang. Buat ujian perdagangan langsung di FMZ.

1. Pembentukan

Selepas menyambung ke Aplikasi dYdX v4 dengan berjaya dengan menggunakan dompet cryptocurrency (saya menggunakan dompet imToken di sini), menuntut aset ujian anda dan kemudian mengeksport mnemonik untuk akaun dYdX v4 semasa anda (berasal dari dompet anda).

img

Mengkonfigurasi mnemonic pada platform FMZ. Di sini kita menggunakan kaedah fail tempatan untuk mengkonfigurasi ia (anda juga boleh mengisi secara langsung dan mengkonfigurasi ia ke platform. mnemonic dikonfigurasi selepas penyulitan, bukan dalam teks biasa).

  • Fail mnemonic: mnemonic.txt

img

Letakkan ia dalam direktori folder ID perdagangan langsung di bawah direktori docker.

  • Mengatur pertukaran di FMZ

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

Isi kotak penyuntingan mnemonik:file:///mnemonic.txt, laluan sebenar yang sepadan adalah:docker directory/logs/storage/594291.

img

2. beralih ke dydx v4 Rangkaian Ujian

function main() {
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // Read account information test
    Log(exchange.GetAccount()) 
}

Baca maklumat akaun rangkaian ujian:

{
	"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. Siasatan Maklumat Pasaran

Tidak beralih ke rangkaian ujian, diuji dengan rangkaian 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) +  "`")
}

img

4. Buat Perintah

function main() {
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

    // Limit order, pending order
    var idSell = exchange.CreateOrder("ETH_USD.swap", "sell", 4000, 0.002)
    var idBuy = exchange.CreateOrder("ETH_USD.swap", "buy", 3000, 0.003)

    // Market order
    var idMarket = exchange.CreateOrder("ETH_USD.swap", "buy", -1, 0.01)

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

img

Laman aplikasi dYdX v4:

img

5. Maklumat pesanan

Rangkaian ujian meletakkan dua pesanan terlebih dahulu, ujian mendapatkan pesanan yang sedang menunggu, dan membatalkan pesanan.

function main() {    
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    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) +  "`")
}

img

6. Soalan Maklumat Kedudukan

function main() {
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    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) +  "`")
}

img

7. Pengurusan Sub-akaun

function main() {
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    exchange.IO("restApiBase", "https://dydx-testnet-api.polkachu.com")

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

    // Switch to subaccount subAccountNumber 128 and read account information to check
    exchange.IO("subAccountNumber", 128)

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

Maklumat log:

img

Bertukar ke subaccount yang subAccountNumber 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
}

Kita boleh lihat bahawa sub-akaun dengan sub-akaun nombor 128 telah memindahkan 20 USDC.

8. Dapatkan TxHash dan Panggil REST Node Interface

Menurut perintah, mendapatkan TxHash dan menguji kaedah IO memanggil nod REST

Bagaimana untuk mendapatkan TxHash pesanan? objek pertukaran dydx akan cache TxHash, yang boleh ditanyakan dengan menggunakan ID pesanan. Walau bagaimanapun, selepas strategi dihentikan, peta hash pesanan tx yang disimpan akan dihapuskan.

function main() {
    // Switch the indexer address of the test chain
    exchange.SetBase("https://indexer.v4testnet.dydx.exchange")

    // Switch the ChainId of the test chain
    exchange.IO("chainId", "dydx-testnet-4")

    // Switch the REST node address of the test chain
    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)
    
    // To clear the mapping table, use: 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)
    }
}

img

Mesej yang ditanyakan melalui TxHash:

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

Kandungannya terlalu panjang, jadi berikut adalah beberapa petikan 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": []
			},
      ...

Akhirat

Ujian di atas adalah berdasarkan docker terbaru. anda perlu memuat turun docker terbaru untuk menyokong dYdX v4 DEX

Terima kasih atas sokongan anda dan terima kasih kerana membaca.


Lebih lanjut