Tài nguyên đang được tải lên... tải...

Thực hành định lượng của DEX Exchange (1) -- dYdX v4 User Guide

Tác giả:FMZ~Lydia, Tạo: 2024-12-26 15:32:24, Cập nhật: 2024-12-26 17:36:31

Lời giới thiệu

Với sự gia tăng nhanh chóng của sàn giao dịch phi tập trung (DEX) trong lĩnh vực giao dịch tiền điện tử, các nhà giao dịch định lượng đã dần chuyển sang các nền tảng này để giao dịch tự động hiệu quả. Là một trong những nền tảng giao dịch phi tập trung phổ biến nhất, dYdX cung cấp các chức năng giao dịch mạnh mẽ và hỗ trợ giao dịch hợp đồng vĩnh viễn tương lai. Phiên bản mới nhất của nó v4 tối ưu hóa hiệu suất và trải nghiệm người dùng, làm cho nó trở thành lựa chọn đầu tiên cho nhiều nhà giao dịch định lượng.

Bài viết này sẽ giới thiệu cách thực hành giao dịch định lượng trên dYdX v4, bao gồm cách sử dụng API của nó để giao dịch, thu thập dữ liệu thị trường và quản lý tài khoản.

  • Chuyển môi trường thử nghiệm
  • Tìm kiếm thông tin thị trường
  • Thông tin đặt hàng và truy vấn thông tin vị trí
  • Đặt hàng
  • Quản lý tài khoản phụ
  • Yêu cầu phương thức nút

dYdX v4 DEX

  • Trang ứng dụng dYdX testnet

img

  • NhưdYdX v3Với Ethereum, giao dịch tạo ra phần thưởng, đó là phần thưởngdYdX tokens.

Kết nối ví, đăng nhập và thông tin cấu hình

Địa chỉ ứng dụng dYdX v4 hiện tại là:

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

Sau khi mở trang ứng dụng, có một nút để kết nối với ví ở góc trên bên phải.

Nếu bạn muốn thử nghiệm và làm quen với môi trường mạng thử nghiệm trước tiên, bạn có thể sử dụng mạng thử nghiệm:

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

Ngoài ra, nhấp vào nút kết nối ví ở góc trên bên phải, quét mã để kết nối ví và xác minh chữ ký. Sau khi ví được kết nối thành công, địa chỉ dydx v4 sẽ tự động được tạo ra. Địa chỉ này sẽ được hiển thị ở góc trên bên phải của trang Ứng dụng. Nhấp vào nó và một menu sẽ bật lên. Có các hoạt động như sạc, rút tiền và chuyển tiền. Một trong những khác biệt giữa dYdX mainnet (môi trường sản xuất) và testnet là khi bạn nhấp vào sạc trên testnet, 300 tài sản USDC sẽ tự động được sạc bằng vòi phun để thử nghiệm. Nếu bạn muốn thực hiện giao dịch thực trên dYdX, bạn cần sạc tài sản USDC. Sạc lại cũng rất thuận tiện và tương thích với nhiều tài sản và chuỗi để sạc lại.

  • Địa chỉ tài khoản dYdX v4 Địa chỉ tài khoản dYdX v4 được bắt nguồn từ địa chỉ ví. Địa chỉ tài khoản dYdX v4 trông như sau:dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, đó là một địa chỉ bắt đầu với dydx1.

  • Mnemonics Bạn có thể sử dụng nút Export Password trong menu góc trên bên phải để xuất mnemonics của tài khoản địa chỉ dYdX hiện tại. Khi thêm một trao đổi trên nền tảng FMZ, bạn cần cấu hình mnemonic này.

Các mnemonics có thể được cấu hình trực tiếp trên nền tảng FMZ hoặc lưu cục bộ trên dock. Khi sử dụng đối tượng trao đổi dydx v4, nội dung tệp ghi các mnemonics sẽ được đọc, sẽ được chứng minh trong phần thực tế của bài viết này.

Sự khác biệt giữa Mainnet và Testnet

Môi trường testnet khác với môi trường mainnet trong một số khía cạnh.

  • Chuyển tài sản vào tài khoản phụ. Mạng chính có một cơ chế dọn dẹp tài khoản phụ.subAccountNumber >= 128, nếu tài khoản phụ của ID không có vị trí, tài sản sẽ tự động được xóa vào tài khoản phụ có số tài khoản phụ là 0. Trong quá trình thử nghiệm, nó được tìm thấy rằng mạng thử nghiệm không có cơ chế này (hoặc các điều kiện kích hoạt khác nhau và nó đã không được kích hoạt trong mạng thử nghiệm).
  • Một số tên đặc biệt. Token gốc dydx có tên khác nhau: mainnetDYDX, testnetDv4TNT
  • Cấu hình địa chỉ, chẳng hạn như mã số chuỗi, địa chỉ nút, địa chỉ chỉ mục, v.v. Có rất nhiều nút và cấu hình, đây là một trong số đó:

Mạng chính: Địa chỉ chỉ mục:https://indexer.dydx.tradeID chuỗi:dydx-mainnet-1REST Node:https://dydx-dao-api.polkachu.com:443

Testnet: Địa chỉ chỉ mục:https://indexer.v4testnet.dydx.exchangeID chuỗi:dydx-testnet-4REST Node:https://dydx-testnet-api.polkachu.com

Kiến trúc giao thức dYdX v4

Giao thức dYdX v4 được phát triển dựa trên hệ sinh thái vũ trụ.

  • Một trình lập chỉ mục chịu trách nhiệm truy vấn thông tin ticker, thông tin tài khoản, vv.
  • Dydx blockchain thông báo đặt hàng, thông báo hủy đặt hàng, chuyển giao thông điệp, vv

Chỉ mục

Dịch vụ lập chỉ mục cung cấp các giao thức REST và Websocket.

  • REST giao thức Giao diện giao thức REST hỗ trợ truy vấn thông tin thị trường, thông tin tài khoản, thông tin vị trí, thông tin đơn đặt hàng và các truy vấn khác, và đã được đóng gói như một giao diện API thống nhất trên nền tảng FMZ.

  • Giao thức WebSocket Trên nền tảng FMZ, bạn có thể sử dụng chức năng Dial để tạo kết nối Websocket và đăng ký thông tin thị trường.

Cần lưu ý rằng trình lập chỉ mục của dydx v4 có cùng một vấn đề như các sàn giao dịch tập trung, tức là việc cập nhật dữ liệu không phải là kịp thời. Ví dụ, đôi khi bạn có thể không thể tìm thấy lệnh nếu bạn truy vấn nó ngay sau khi đặt lệnh.Sleep(n)) một số hoạt động trước khi truy vấn.

Dưới đây là một ví dụ về việc sử dụng hàm Dial để tạo kết nối API Websocket và đăng ký dữ liệu sổ đặt hàng:

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) + "`")
    }
}

dYdX Chain Node Message Broadcast

Các tin nhắn được sử dụng phổ biến nhất trong giao dịch là tin nhắn đặt hàng, tin nhắn hủy đặt hàng và tin nhắn chuyển tiền.

  • Tóm tắt thông điệp lệnh
{
  "@type": "/dydxprotocol.clob.MsgPlaceOrder",
  "order": {
    "orderId": {
      "subaccountId": {
        "owner": "xxx"
      },
      "clientId": xxx,
      "orderFlags": 64,
      "clobPairId": 1
    },
    "side": "SIDE_BUY",
    "quantums": "2000000",
    "subticks": "3500000000",
    "goodTilBlockTime": 1742295981
  }
}
  • Trật tự giới hạn: Trong hàm lệnh được đóng gói trên nền tảng FMZ, giá trị orderFlags được sử dụng cho các lệnh giới hạn là:ORDER_FLAGS_LONG_TERM = 64 # Long-term orderTheo các hạn chế của giao thức dydx v4, thời gian hợp lệ đặt hàng dài nhất được sử dụng, đó là 90 ngày (tất cả các loại lệnh trên dydx v4 đều có thời gian hợp lệ).

  • Trật tự thị trường: Trong hàm lệnh được đóng gói trên nền tảng FMZ, giá trị orderFlags được sử dụng cho các lệnh thị trường là:ORDER_FLAGS_SHORT_TERM = 0 # Short-term order, theo các khuyến nghị của giao thức dydx v4:

// Đề xuất đặt giá oracle - 5% hoặc thấp hơn cho SELL, giá oracle + 5% cho BUY

Vì nó không phải là lệnh thị trường thực sự, giá Oracle được sử dụng, cộng hoặc trừ 5% trượt như lệnh thị trường. Thời gian hiệu lực của lệnh ngắn hạn cũng khác với thời gian hiệu lực của lệnh dài hạn.

  • Đơn đặt hàng: Vì hoạt động đặt hàng được thực hiện trực tiếp trên chuỗi, sẽ không có ID đặt hàng được tạo ra bởi trình lập chỉ mục sau khi thông điệp được phát sóng và lệnh lập chỉ mục không thể được sử dụng làm giá trị trả về của hàm đặt hàng nền tảng. Để đảm bảo tính độc đáo của ID đặt hàng và độ chính xác của truy vấn đặt hàng, ID đặt hàng được trả về bao gồm các thông tin sau (loại biệt bằng dấu phẩy):

Các cặp giao dịch Địa chỉ tài khoản hiện tại dydx Số tài khoản phụ (subaccountNumber) clientId (được tạo ngẫu nhiên) clobPairId (định dạng ký hiệu giao dịch) orderTờ cờ goodTilData (tỷ số giây)

  • Tóm tắt thông điệp hủy đặt hàng
{
  "@type": "/dydxprotocol.clob.MsgCancelOrder",
  "orderId": {
    "subaccountId": {
      "owner": "xxx"
    },
    "clientId": 2585872024,
    "orderFlags": 64,
    "clobPairId": 1
  },
  "goodTilBlockTime": 1742295981
}

ID lệnh được trả về bởi giao diện lệnh nền tảng FMZ cần được truyền vào.

  • Tóm tắt tin nhắn chuyển
{
  "@type": "/dydxprotocol.sending.MsgCreateTransfer",
  "transfer": {
    "sender": {
      "owner": "xxx"
    },
    "recipient": {
      "owner": "xxx",
      "number": 128
    },
    "amount": "10000000"
  }
}

Nhiều tài khoản phụ có thể được tạo dưới địa chỉ dydx v4 hiện tại. Tài khoản phụ với subAccountNumber 0 là tài khoản phụ được tạo tự động đầu tiên. ID tài khoản phụ với subAccountNumber lớn hơn hoặc bằng 128 được sử dụng cho giao dịch vị trí cô lập, đòi hỏi ít nhất 20 tài sản USDC. Ví dụ, bạn có thể đi từ subAccountNumber 0 -> 128, hoặc từ subAccountNumber 128 -> 0.

FMZ Platform dYdX v4 Thực hành

Nội dung trên giải thích một số chi tiết về gói một cách ngắn gọn. Tiếp theo, hãy thực hành việc sử dụng cụ thể. Ở đây chúng ta sử dụng mạng thử nghiệm dYdX v4 để chứng minh. Mạng thử nghiệm về cơ bản giống như mạng chính, và có một vòi nước tự động để nhận tài sản thử nghiệm. Hoạt động triển khai docker sẽ không được lặp lại. Tạo một thử nghiệm giao dịch trực tiếp trên FMZ.

1. cấu hình

Sau khi kết nối với ứng dụng dYdX v4 thành công bằng cách sử dụng ví tiền điện tử (tôi sử dụng ví imToken ở đây), yêu cầu tài sản thử nghiệm của bạn và sau đó xuất mnemonic cho tài khoản dYdX v4 hiện tại của bạn (được bắt nguồn từ ví của bạn).

img

Thiết lập mnemonic trên nền tảng FMZ. Ở đây chúng tôi sử dụng phương thức tập tin cục bộ để cấu hình nó (bạn cũng có thể điền trực tiếp và cấu hình nó trên nền tảng.

  • Tệp mnemonic: mnemonic.txt

img

Đặt nó trong thư mục thư mục ID giao dịch trực tiếp dưới thư mục docker.

  • Thiết lập trao đổi trên FMZ

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

Điền vào hộp chỉnh sửa ký ức:file:///mnemonic.txt, đường thực tế tương ứng là:docker directory/logs/storage/594291.

img

2. Chuyển sang mạng thử nghiệm dydx v4

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

Đọc thông tin tài khoản mạng thử nghiệm:

{
	"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. Nghiên cứu thông tin thị trường

Không chuyển sang mạng thử nghiệm, được thử nghiệm với mạng chính

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. Đặt đơn đặt hàng

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

Trang ứng dụng dYdX v4:

img

5. Thông tin đặt hàng

Mạng thử nghiệm đặt hai đơn đặt hàng trước, thử nghiệm lấy các đơn đặt hàng đang chờ và hủy các đơn đặt hàng.

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. Tìm kiếm thông tin vị trí

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. Quản lý tài khoản phụ

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

Thông tin nhật ký:

img

Chuyển sang tài khoản con có số tài khoản con là 128, và dữ liệu được trả về bởi GetAccount là:

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

Có thể thấy rằng tài khoản phụ với tài khoản phụ số 128 đã chuyển 20 USDC.

8. Nhận TxHash và gọi giao diện REST Node

Theo lệnh, lấy TxHash và kiểm tra phương pháp của IO gọi REST node

Làm thế nào để lấy TxHash của một lệnh? Đối tượng trao đổi dydx sẽ lưu trữ bộ nhớ cache TxHash, có thể được truy vấn bằng cách sử dụng ID lệnh. Tuy nhiên, sau khi chiến lược được dừng lại, bản đồ hash tx được lưu trữ sẽ được xóa.

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

Tin nhắn được truy vấn qua TxHash:

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

Nội dung quá dài, vì vậy đây là một số đoạn trích để chứng minh:

{
	"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": []
			},
      ...

Sự kết thúc

Các bài kiểm tra trên dựa trên docker mới nhất. Bạn cần tải xuống docker mới nhất để hỗ trợ dYdX v4 DEX

Cảm ơn sự ủng hộ của các bạn và cảm ơn đã đọc.


Thêm nữa