avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

DEX Exchange Quantitative Practice (1) -- dYdX v4 Benutzerhandbuch

Erstellt in: 2024-12-24 17:09:32, aktualisiert am: 2024-12-26 21:41:46
comments   0
hits   1049

[TOC]

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Vorwort

Mit dem rasanten Aufstieg dezentraler Börsen (DEX) im Bereich des Kryptowährungshandels greifen quantitative Händler nach und nach auf diese Plattformen zurück, um effizienten automatisierten Handel zu betreiben. Als eine der beliebtesten dezentralen Handelsplattformen bietet dYdX leistungsstarke Handelsfunktionen und unterstützt den Handel mit unbefristeten Futures-Kontrakten. Die neueste Version v4 optimiert Leistung und Benutzererfahrung und ist damit die erste Wahl für viele quantitative Händler.

In diesem Artikel erfahren Sie, wie Sie quantitativen Handel mit dYdX v4 betreiben und wie Sie die API zum Handeln, Abrufen von Marktdaten und Verwalten von Konten verwenden.

  • Umschalten der Testumgebung
  • Marktinformationsabfrage
  • Abfrage von Bestellinformationen und Positionsinformationen
  • Bestellung aufgeben
  • Unterkontenverwaltung
  • Knotenmethodenanforderung

dYdX v4 DEX

  • dYdX Testnet App-Seite

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

  • UnddYdX v3Ebenso generieren Transaktionen Belohnungen, BelohnungendYdXToken.

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Wallet-Verbindung, Login und Konfigurationsinformationen

Der vorherige DEX-Austausch des dYdX v3-Protokolls war offline. Die aktuelle dYdX v4-App-Adresse lautet:

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

Nach dem Öffnen der App-Seite befindet sich oben rechts ein Button zum Verbinden mit dem Wallet. Scanne den QR-Code, um eine Verbindung mit dem Wallet herzustellen.

Wenn Sie zunächst die Testnetzwerkumgebung testen und sich mit ihr vertraut machen möchten, können Sie das Testnetzwerk verwenden:

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

Klicken Sie außerdem oben rechts auf die Schaltfläche „Wallet verbinden“, scannen Sie den QR-Code, um das Wallet zu verbinden, und überprüfen Sie die Signatur. Nachdem die Wallet erfolgreich verbunden wurde, wird automatisch eine dydx v4-Adresse generiert. Diese Adresse wird in der oberen rechten Ecke der App-Seite angezeigt. Nach dem Anklicken wird ein Menü eingeblendet. Hierzu gehören Vorgänge wie Aufladen, Abheben und Überweisen. Einer der Unterschiede zwischen dem dYdX-Mainnet (Produktionsumgebung) und dem Testnet besteht darin, dass beim Klicken auf die Aufladeschaltfläche im Testnet automatisch 300 USDC-Assets zum Testen in den Faucet eingezahlt werden. Wenn Sie echte Transaktionen auf dYdX durchführen möchten, müssen Sie USDC-Vermögenswerte einzahlen. Das Aufladen ist auch sehr bequem und mit mehreren Vermögenswerten und Ketten kompatibel.

  • dYdX v4-Kontoadresse Die dYdX v4-Kontoadresse wird aus der Wallet-Adresse abgeleitet. Die dYdX v4-Kontoadresse sieht folgendermaßen aus:dydx1xxxxxxxxxxxxxxxxxxxxq2ge5jr4nzfeljxxxx, ist die Adresse, die mit dydx1 beginnt. Diese Adresse kann in Blockchain-Explorern abgefragt werden.

  • Mnemonik Sie können die Mnemonik des aktuellen dYdX-Adresskontos exportieren, indem Sie im Menü oben rechts auf die Schaltfläche „Passwort exportieren“ klicken. Wenn Sie auf der FMZ-Plattform eine Börse hinzufügen, müssen Sie diese Mnemonik konfigurieren.

Mnemonics können direkt auf der FMZ-Plattform konfiguriert oder lokal auf dem Verwahrer gespeichert werden. Bei Verwendung des dydx v4-Austauschobjekts wird der Dateiinhalt, der die Mnemonics aufzeichnet, gelesen, was im praktischen Teil dieses Artikels demonstriert wird.

Unterschiede zwischen Mainnet und Testnet

Die Testnet-Umgebung unterscheidet sich in einigen Aspekten von der Mainnet-Umgebung. Hier sind einige einfache Unterschiede.

  • Vermögensübertragung auf Unterkonten. Das Hauptnetzwerk verfügt über einen Bereinigungsmechanismus für Unterkonten.subAccountNumber >= 128Wenn das Unterkonto mit dieser ID keine Positionen aufweist, werden die Vermögenswerte automatisch auf das Unterkonto mit der Unterkontonummer 0 ausgezahlt. Beim Testen stellte sich heraus, dass das Testnetzwerk nicht über einen solchen Mechanismus verfügte (oder die Auslösebedingungen waren anders und er wurde im Testnetzwerk nicht ausgelöst).

  • Einige Token-Namen. Der native Token dydx heißt anders: MainnetDYDX, TestnetzwerkDv4TNT

  • Adresskonfiguration, wie Ketten-ID, Knotenadresse, Indexeradresse usw. Es gibt viele Knoten und Konfigurationen, hier ist eine davon:

    • Hauptnetz: Indexeradresse:https://indexer.dydx.trade Ketten-ID:dydx-mainnet-1 REST-Knoten:https://dydx-dao-api.polkachu.com:443

    • Testnetz: Indexeradresse:https://indexer.v4testnet.dydx.exchange Ketten-ID:dydx-testnet-4 REST-Knoten:https://dydx-testnet-api.polkachu.com

dYdX v4-Protokollarchitektur

Das dYdX v4-Protokoll wurde basierend auf dem Cosmos-Ökosystem entwickelt. Der transaktionsbezogene Inhalt des dYdX v4 DEX-Systems besteht hauptsächlich aus zwei Teilen:

  • Ein Indexer, der für die Abfrage von Marktinformationen, Kontoinformationen usw. zuständig ist.
  • dydx-Blockchain-Bestellnachrichten, Bestellstornierungsnachrichten, Überweisungsnachrichten usw.

Indexer

Der Indexerdienst bietet REST- und Websocket-Protokolle.

  • REST-Protokoll Die REST-Protokollschnittstelle unterstützt die Abfrage von Marktinformationen, Kontoinformationen, Positionsinformationen, Auftragsinformationen usw. und wurde als einheitliche API-Schnittstelle auf der FMZ-Plattform gekapselt.

  • WebSocket-Protokoll Auf der FMZ-Plattform können Sie über die Dial-Funktion eine Websocket-Verbindung herstellen und Marktinformationen abonnieren.

Es ist zu beachten, dass der dydx v4-Indexer das gleiche Problem hat wie der zentralisierte Austausch, d. h. die Datenaktualisierungen erfolgen nicht so zeitnah. Beispielsweise kann die Bestellung manchmal nicht gefunden werden, wenn unmittelbar nach der Bestellung abgefragt wird. Es wird empfohlen, nach bestimmten Vorgängen (Sleep(n)) Warten Sie einige Sekunden, bevor Sie die Abfrage erneut durchführen.

Hier ist ein Beispiel für die Verwendung der Dial-Funktion zum Herstellen einer Websocket-API-Verbindung und Abonnieren von Orderbuchdaten:

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

dYdX-Kettenknoten-Nachrichtenübertragung

Die am häufigsten verwendeten Nachrichten bei Transaktionen sind Bestellnachrichten, Bestellstornierungsnachrichten und Überweisungsnachrichten.

  • Zusammenfassung der Bestellnachricht
  {
    "@type": "/dydxprotocol.clob.MsgPlaceOrder",
    "order": {
      "orderId": {
        "subaccountId": {
          "owner": "xxx"
        },
        "clientId": xxx,
        "orderFlags": 64,
        "clobPairId": 1
      },
      "side": "SIDE_BUY",
      "quantums": "2000000",
      "subticks": "3500000000",
      "goodTilBlockTime": 1742295981
    }
  }
  • Limitierte Bestellung: In der auf der FMZ-Plattform gekapselten Auftragsfunktion lautet der für Limitaufträge verwendete OrderFlags-Wert:ORDER_FLAGS_LONG_TERM = 64 # 长期订单Gemäß den Einschränkungen des DYDX v4-Protokolls wird die längste Auftragsgültigkeitsdauer verwendet, die 90 Tage beträgt (alle Auftragsarten bei DYDX v4 haben eine Gültigkeitsdauer).

  • Marktauftrag: In der auf der FMZ-Plattform gekapselten Auftragsfunktion lautet der von der Marktorder verwendete OrderFlags-Wert:ORDER_FLAGS_SHORT_TERM = 0 # 短期订单, gemäß den Empfehlungen des DYDX v4-Protokolls:

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

    Da es sich nicht um eine echte Marktorder handelt, wird der Orakelpreis plus oder minus 5 % Slippage als Marktorder verwendet. Auch die Gültigkeitsdauer von kurzfristigen Aufträgen unterscheidet sich von der von langfristigen Aufträgen. Kurzfristige Aufträge verwenden die Gültigkeitsdauer der Blockhöhe. Gemäß der Empfehlung von dydx v4 wird sie auf den aktuellen Block + 10 Blockhöhen eingestellt. bevor es abläuft.

  • Bestellnummer: Da die Bestelloperation direkt in der Kette ausgeführt wird, wird vom Indexer nach der Übertragung der Nachricht keine Bestell-ID generiert, und die Indexerbestellung kann nicht als Rückgabewert der Plattform-Bestellfunktion verwendet werden. Um die Eindeutigkeit sicherzustellen der Auftrags-ID und der Genauigkeit der Auftragsabfrage wird die Indexer-Bestellung zurückgegeben. Die Auftrags-ID besteht aus den folgenden Informationen (durch Komma getrennt):

    • Handelspaare
    • dydx Girokontoadresse
    • Unterkontonummer (subaccountNumber)
    • Client-ID (zufällig generiert)
    • clobPairId (Transaktionssymbol-ID)
    • orderFlags
    • goodTilData (Millisekunden)
  • Zusammenfassung der Nachrichten zur Auftragsstornierung

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

Es muss die von der Bestellschnittstelle der FMZ-Plattform zurückgegebene Bestell-ID übergeben werden.

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

Unter der aktuellen dydx v4-Adresse können viele Unterkonten erstellt werden. Das Unterkonto mit der SubAccountNumber 0 ist das erste automatisch erstellte Unterkonto. Die Unterkonto-ID mit der SubAccountNumber größer oder gleich 128 wird für den isolierten Positionshandel verwendet. wofür mindestens 20 USDC-Vermögenswerte erforderlich sind. Sie können beispielsweise von subAccountNumber 0 -> 128 oder von subAccountNumber 128 -> 0 wechseln. Für die Übertragung ist der Verbrauch einer Gasgebühr erforderlich. Für die Gasgebühr können USDC- und Dydx-Token verwendet werden.

FMZ-Plattform dYdX v4 Praxis

Der obige Inhalt erläutert kurz einige Verpackungsdetails. Als nächstes üben wir die spezifische Verwendung. Hier verwenden wir das dYdX v4-Testnetzwerk zur Demonstration. Das Testnetzwerk ist im Wesentlichen dasselbe wie das Hauptnetzwerk und es gibt einen automatischen Wasserhahn zum Empfangen von Testressourcen . Der Wächter setzt mich ein Ich werde nicht näher auf die Operation eingehen, und einen echten Test auf FMZ durchführen.

1. Konfiguration

Nachdem Sie mithilfe eines Kryptowährungs-Wallets (ich verwende hier das imToken-Wallet) erfolgreich eine Verbindung mit der dYdX v4-App hergestellt haben, fordern Sie Ihre Test-Assets an und exportieren Sie dann die Mnemonik für Ihr aktuelles dYdX v4-Konto (abgeleitet aus Ihrem Wallet).

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Konfigurieren Sie die Mnemonik auf der FMZ-Plattform. Hier verwenden wir die lokale Dateimethode, um sie zu konfigurieren (Sie können sie auch direkt ausfüllen und auf der Plattform konfigurieren. Die Mnemonik wird nach der Verschlüsselung konfiguriert, nicht im Klartext).

  • Mnemonische Datei: mnemonic.txt

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Legen Sie es im Ordnerverzeichnis mit der realen Datenträger-ID unter dem Verwahrerverzeichnis ab. Natürlich kann es auch in anderen Verzeichnissen abgelegt werden (der spezifische Pfad muss während der Konfiguration angegeben werden).

  • Konfigurieren Sie den Austausch auf FMZ

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

Füllen Sie das mnemonische Bearbeitungsfeld aus:file:///mnemonic.txt, der entsprechende tatsächliche Pfad lautet:托管者所在目录/logs/storage/594291

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

2. Wechseln Sie zum dydx v4-Testnetzwerk

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

Lesen Sie die Kontoinformationen des Testnetzwerks:

{
	"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. Marktinformationsanfrage

Nicht ins Testnetz gewechselt, mit Hauptnetz getestet

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

4. Bestellung aufgeben

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

dYdX v4 App-Seite:

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

5. Bestellinformationen

Das Testnetzwerk platziert zwei Aufträge im Voraus, testet den Erhalt der aktuell ausstehenden Aufträge und storniert die Aufträge.

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

6. Abfrage von Positionsinformationen

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

7. Unterkontenverwaltung

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Wechseln Sie zum Unterkonto, dessen Unterkontonummer 128 ist. Die von GetAccount zurückgegebenen Daten lauten:

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

Es ist ersichtlich, dass das Unterkonto mit der Unterkontonummer 128 20 USDC überwiesen hat.

8. Holen Sie sich TxHash und rufen Sie die REST-Knotenschnittstelle auf

Holen Sie sich gemäß der Reihenfolge TxHash und testen Sie die Methode des IO-Aufrufs des REST-Knotens

Wie erhält man den TxHash einer Bestellung? Das Exchange-Objekt dydx speichert den TxHash im Cache, der dann über die Bestell-ID abgefragt werden kann. Nach dem Stoppen der Strategie wird die zwischengespeicherte Order-Tx-Hash-Map jedoch gelöscht.

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

DEX Exchange Quantitative Practice (1) – dYdX v4 Benutzerhandbuch

Über TxHash abgefragte Nachrichten:

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

Der Inhalt ist zu lang, deshalb hier einige Auszüge zur Veranschaulichung:

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

Die obigen Tests basieren auf dem neuesten Custodian. Sie müssen den neuesten Custodian herunterladen, um dYdX v4 DEX zu unterstützen

Vielen Dank für Ihre Unterstützung und fürs Lesen.