[TOC]
Dies ist der dritte Artikel über die quantitative Praxis von DEX-Börsen. Dieses Mal stellen wir die Nutzungsanleitung des Vertex-Protokolls vor.
Im Rahmen traditioneller dezentraler Börsen (DEX) müssen quantitative Händler häufig Kompromisse eingehen: Entweder sie akzeptieren die hohe Slippage und die geringe Ausführungseffizienz des Automated Market Maker-Modells (AMM) oder sie geraten in das technische Dilemma der kettenübergreifenden Liquiditätsfragmentierung und einzelner Derivatefunktionen. Die Entstehung des Vertex-Protokolls definiert die On-Chain-Grenzen quantitativer Strategien durch ein Fusionsexperiment auf „dezentraler + institutioneller Ebene“ neu – es gibt hier kein „Wähle eines von beiden“-Dilemma, sondern nur die ultimative Balance zwischen Geschwindigkeit, Tiefe und Freiheit.
Als erster DEX, der einen einheitlichen Multi-Chain-Liquiditätspool, ein Hybrid Order Book (CLOB) und einen eingebetteten Währungsmarkt integriert, legt Vertex den Schwerpunkt auf „zentralisierte Erfahrung, dezentrale Seele“ und eröffnet einen einzigartigen Weg für quantitative Händler:
Eine neue Definition von Geschwindigkeit und Flüssigkeit
Mit der kontinuierlichen Weiterentwicklung der Blockchain-Technologie verschwimmt die Grenze zwischen traditionellen zentralisierten Börsen (CEX) und dezentralen Börsen (DEX) allmählich. Als Dreh- und Angelpunkt der Vertex-Plattform gestaltet Vertex Edge nicht nur die Transaktionsgeschwindigkeit und Liquidität neu, sondern kombiniert durch die kettenübergreifende Integration auch perfekt hervorragende Order-Matching-Technologie und Vorteile der Selbstverwahrung und bietet so globalen Händlern ein neues DeFi-Erlebnis.
Vereinheitlichung der Cross-Chain-Liquidität: Abbau der Liquiditätsfragmentierung Auf traditionellen Märkten ist die Liquidität zwischen verschiedenen Ketten oft fragmentiert, was dazu führt, dass Händler nicht in den Genuss der besten Transaktionspreise und -tiefe kommen. In diesem Zusammenhang wurde Vertex Edge geboren, das die synchrone gemeinsame Nutzung permanenter Liquidität über mehrere Ketten hinweg durch ein einheitliches Orderbuchnetzwerk ermöglicht. Derzeit deckt Vertex Edge die unbefristete Vertragsliquidität auf 7 Mainstream-Ketten ab, darunter Arbitrum, Base, Sei, Blast, Mantle, Sonic und Abstract, sodass sich Händler keine Sorgen mehr über die Liquiditätsstreuung machen müssen und zum besten Preis handeln können, wodurch wirklich eine nahtlose Verbindung der globalen Liquidität erreicht wird.
Hybrider Orderbuchhandel: die perfekte Balance zwischen ultraschnellem Matching und On-Chain-Abwicklung Vertex Edge verwendet ein hybrides Orderbuch-Handelsmodell. Zu seinen Kerntechnologien gehören:
Off-Chain-Orderbook-Matcher: Verwendet einen ultraschnellen Off-Chain-Matching-Mechanismus, um ein Order-Matching mit einer Latenz von nur 5–15 Millisekunden zu erreichen, vergleichbar mit den meisten zentralisierten Börsen; On-Chain-Risiko-Engine und AMM: Auf jeder unterstützten Kette werden Risikomanagementsysteme und automatisierte Market Maker (AMMs) eingesetzt, um sicherzustellen, dass Aufträge nach der Zuordnung sicher und transparent abgewickelt werden können. Diese Architektur gewährleistet nicht nur eine extrem schnelle Transaktionsreaktion, sondern bietet Benutzern durch On-Chain-Abwicklung auch dezentrale Sicherheit, sodass Händler von einer Leistung auf CEX-Niveau profitieren und gleichzeitig die Unabhängigkeit der Selbstverwahrung von Vermögenswerten wahren können.
Multi-Account-Funktion: Verwalten Sie mehrere Konten in einer einzigen Wallet und verteilen Sie Geldmittel effizienter. Gehebelte Spot-Positionen: Nutzen Sie alle Vermögenswerte als Marge, um eine höhere Kapitaleffizienz zu erreichen; Flexibles Risikomanagement: Einlagen, Positionen sowie Gewinn- und Verlustdaten werden einheitlich berücksichtigt, um die Risikobelastung präzise zu steuern.
Adresse der Login-Seite „Vertex Protocol“:
Vertex ist dasselbe wie die meisten DEXs. Nachdem Sie sich bei der Dapp angemeldet haben, müssen Sie sich zur Autorisierung mit der Wallet verbinden. Das Unterkontosystem von Vertex wird anhand eines Labels unterschieden. Das Label nimmt an der Wallet-Adressberechnung teil, um eine Unterkonto-Wallet-Adresse zu erhalten. Gleichzeitig ist diese Adresse autorisiert, Bestellungen und andere Vorgänge aufzugeben.
Verwenden Sie beispielsweiseWalletConnectDie Wallet-Adresse beim Verbinden lautet:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43
, die Standardbezeichnung lautet „Standard“ und die berechnete Unterkontoadresse lautet:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c4364656661756c740000000000
. Die Standard-Tags sind:64656661756c740000000000
。
Vertex unterstützt das Aufladen mehrerer Assets. Im Allgemeinen laden Sie USDC als Marge auf und verwenden die verbundene Wallet direkt zum Übertragen von Transaktionen. Es ist zu beachten, dass Vorgänge wie Abheben, Überweisen, Senden von Token und Übertragen von Unterkonten auf Vertex USDC verbrauchen und die Gebühren nicht niedrig sind. Daher müssen diese Vorgänge mit Vorsicht aufgerufen werden.
Wechseln Sie zu einer anderen Kette:
Auf dem Scheitelpunkt haben verschiedene Ketten unterschiedliche Konfigurationsinformationen wie Knoten, Indexer und Ketten-IDs. Die Standardkette für die FMZ-Kapselung istArbitrum One
Es ist möglich.Log(HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=contracts"))
Fragen Sie die ID einer Kette, bereitgestellte Vertragsinformationen usw. ab.
Nachdem Sie sich bei FMZ.COM angemeldet haben, wählen Sie auf der Exchange-Konfigurationsseite „Kryptowährung“ und dann Vertex Exchange. Sie können den Wallet-Proxy-Schlüssel direkt auf der Dapp konfigurieren. Natürlich können Sie auch den privaten Wallet-Schlüssel konfigurieren. Auf Vertex können Sie die Schnittstelle verwenden, um die Autorisierung/Deautorisierung des Proxy-Schlüssels und andere Vorgänge zu verwalten, was auch bequemer ist.
Proxy-Schlüssel:
Beispielsweise auf der Frontend-Seite der Vertex DEX-Börse: Chrome-Browser (Debugging aktivieren) -> Anwendung -> Lokaler Speicher -> https://app.vertex -> Vertex-Benutzereinstellungen
Vertex Exchange konfigurieren
Auf FMZ müssen zwei Dinge konfiguriert werden. Das erste ist die Wallet-Adresse (nicht die Adresse des zum Signieren verwendeten Proxy-Schlüssels, es muss die mit der Dapp verbundene Wallet-Adresse sein). Der zweite ist der geheime Schlüssel, der zum Signieren verwendet wird (es kann sich um einen privaten Wallet-Schlüssel oder einen Proxy-Schlüssel handeln). Da Proxy-Schlüssel verwendet werden können, sind die konfigurierte Wallet-Adresse und der Schlüssel nicht notwendigerweise ein Paar.
Das Unterkontensystem von Vertex wird durch Tags identifiziert. Das Standard-Tag, das auf FMZ verwendet wird, istdefault
Das Hauptkonto des Tags. Wenn Sie wechseln müssen, können Sie es im Code verwenden:
exchange.IO("subAccountTag", "default") // 切换到主子账号
exchange.IO("subAccountTag", "test01") // 切换到标签名为 test01 的子账号
Nachdem wir die Exchange-Konfigurationsinformationen konfiguriert und ein Custodian-Programm bereitgestellt haben, das auf die Vertex-Schnittstelle zugreifen kann, können wir mit dem Schreiben von Code für praktische Vorgänge beginnen.
Wir verwenden zum Testen das Haupt-Unterkonto (das Unterkonto mit dem Tag: default) und wir verwendenArbitrumNetzwerk.
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", "CtValCcy"
],
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, market.CtValCcy
])
}
LogStatus("`" + JSON.stringify(tbl) + "`")
return markets
}
Es ist ersichtlich, dass der Vertragstyp auf Vertex ein USDC-basierter Vertrag ist, die Marge ist USDC und der Wert eines Vertrags stellt beispielsweise eine entsprechende Währung darBTC_USDC.swap
Das heißt, beim USDC-basierten BTC-Vertrag repräsentiert ein Vertrag eine BTC-Position. Der obige Code zeigt, wie Vertragsmarktinformationen angefordert und verschiedene Inhalte ausgegeben werden.
function main() {
var depths = [{"symbol": "ETH_USDC"}, {"symbol": "SOL_USDC"}, {"symbol": "BTC_USDC"}]
for (var ele of depths) {
ele["depth"] = exchange.GetDepth(ele["symbol"] + ".swap")
}
var tbls = []
for (var ele of depths) {
var tbl = {"type": "table", "title": ele["symbol"], "cols": ["level", "price", "amount"], "rows": []}
var depth = ele["depth"]
for (var i = 0 ; i < 3 ; i++) {
tbl["rows"].push(["卖" + (i + 1), depth.Asks[i].Price, depth.Asks[i].Amount])
}
tbl["rows"].reverse()
for (var i = 0 ; i < 3 ; i++) {
tbl["rows"].push(["买" + (i + 1), depth.Bids[i].Price, depth.Bids[i].Amount])
}
tbls.push(tbl)
}
LogStatus("`" + JSON.stringify(tbls) + "`")
}
function main() {
var arrTrades = [{"symbol": "ETH_USDC"}, {"symbol": "SOL_USDC"}, {"symbol": "BTC_USDC"}]
for (var ele of arrTrades) {
ele["trades"] = exchange.GetTrades(ele["symbol"] + ".swap")
}
var tbls = []
for (var ele of arrTrades) {
var tbl = {"type": "table", "title": ele["symbol"], "cols": ["Time", "Price", "Amount", "side"], "rows": []}
var trades = ele["trades"]
for (var trade of trades) {
tbl["rows"].push([_D(trade.Time), trade.Price, trade.Amount, trade.Type == 0 ? "买入" : "卖出"])
}
tbls.push(tbl)
}
LogStatus("`" + JSON.stringify(tbls) + "`")
}
function main() {
let c = KLineChart({
overlay: true
})
let bars = exchange.GetRecords("SOL_USDC.swap")
if (!bars) {
return
}
bars.forEach(function(bar, index) {
c.begin(bar)
Log(index, bar)
c.close()
})
}
Scheitelpunktdiagramm
FMZ Strategie-Einsatzzeichnung
function main() {
var fundings = exchange.GetFundings()
var tbl = {
"type": "table",
"title": "GetFundings",
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": [],
}
for (var f of fundings) {
tbl["rows"].push([f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate * 100 + " %"])
}
LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
}
Der Finanzierungszyklus beträgt 1 Stunde.
Max Order Size Gets the max order size possible of a given product for a given subaccount.
function main() {
// GET [GATEWAY_REST_ENDPOINT]/query?type=max_order_size&product_id={product_id}&sender={sender}&price_x18={price_x18}&direction={direction}
// price_x18=3000000000000000000000 : 3000 USDC
// product_id=4 : ETH_USDC.swap
// sender=0x123 : e.g. 0x123
return HttpQuery("https://gateway.prod.vertexprotocol.com/query?type=max_order_size&product_id=4&sender=0x123&price_x18=3000000000000000000000&direction=short")
}
Die von der letzten Anfrage zurückgegebenen Daten lauten:{"status":"success","data":{"max_order_size":"170536415320344899"},"request_type":"query_max_order_size"}
Es ist ersichtlich, dass das derzeit verfügbare Vermögen für den unbefristeten Ethereum-Vertrag mit einem Preis von 3000, die maximale Bestellmenge für eine Verkaufsorder beträgt: 0,17 ETH
Linked Signer Retrieves current linked signer of a provided subaccount
function main() {
return HttpQuery("https://gateway.prod.vertexprotocol.com/query?type=linked_signer&subaccount=0x123")
}
Autorisierungsinformationen gefunden:
{“status”:“success”,“data”:{“linked_signer”:“0x79119…”},“request_type”:“query_linked_signer”} Die Adresse „0x79119…“ ist die Proxy-Adresse für die Autorisierung von Auftragstransaktionen bei der Verbindung mit dem Wallet auf der Vertex-Frontend-Seite. Diese Autorisierung kann widerrufen oder hinzugefügt werden (durch API-Aufrufe).
Im Folgenden soll der Fokus dieses Artikels liegen. Wir beschäftigen uns schon seit längerem damit, Transaktionen einfach und schnell auf dezentralen Börsen durchzuführen.
Testen Sie einen einfacheren Handel und platzieren Sie eine normale Limit-Order.
function main() {
var id1 = exchange.CreateOrder("ETH_USDC.swap", "buy", 2000, 0.1)
var id2 = exchange.CreateOrder("SOL_USDC.swap", "buy", 60, 2)
Log("ETH_USDC.swap id1:", id1)
Log("SOL_USDC.swap id2:", id2)
var orders = exchange.GetOrders("USDC.swap")
var tbl = {type: "table", title: "test GetOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
for (var order of orders) {
tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
function main() {
var orders = exchange.GetOrders("USDC.swap")
var tbl = {type: "table", title: "test GetOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
for (var order of orders) {
tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
exchange.CancelOrder(order.Id)
}
LogStatus("`" + JSON.stringify(tbl) + "`")
return exchange.GetOrders()
}
function main() {
// 使用市价单下单持仓
exchange.SetCurrency("ETH_USDC")
exchange.SetContractType("swap")
exchange.Buy(-1, 0.01)
var positions = exchange.GetPositions()
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])
}
LogStatus("`" + JSON.stringify(tbl) + "`")
}
Es ist zu beachten, dass die von der Vertex-API bereitgestellten Daten von den auf der Vertex-Frontend-Seite angezeigten Inhalten abweichen, hauptsächlich aufgrund von Unterschieden beim durchschnittlichen Beteiligungspreis und beim Gewinn und Verlust der Beteiligungen. Dies wurde an das Vertex-Team zurückgemeldet und kann später aktualisiert und aktualisiert werden.
4、Trigger Order
Da die Triggerreihenfolge von vertex unabhängig von endPoint ist,exchange.IO
Wenn Sie eine bedingte Bestellung für eine Funktion aufgeben, müssen Sie angebenTrigger: https://trigger.prod.vertexprotocol.com
, fahren wir mit der praktischen Bedienung fort.
function main() {
// isTrigger : true
var nonce = exchange.IO("nonce", true) // 如果是 Trigger Order 订单用到的 nonce 需要指定 isTrigger : true
// flag , reduceOnly
var expiration = exchange.IO("expiration", "GTC", false) // 设置订单为GTC类型,非只减仓
// params
var params = {
"place_order": {
"product_id": 4,
"order": {
"sender": "0x123...",
"priceX18": "4100000000000000000000",
"amount": "-100000000000000000",
"expiration": expiration,
"nonce": nonce
},
"trigger": {
"price_above": "4000000000000000000000"
}
}
}
return exchange.IO("api", "POST", "https://trigger.prod.vertexprotocol.com/v1/execute", "", JSON.stringify(params))
}
Unter dem Trigger-Endpunkt gibt es außerdem:
Die Aufrufmethode ähnelt „Place Trigger Order“, daher werde ich hier nicht ins Detail gehen.
Das Standard-Unterkonto-Tag ist:default
wechseln wir zu einem benutzerdefinierten Tag:subAcc02
。
function main() {
exchange.IO("subAccountTag", "subAcc02")
return exchange.GetAccount()
}
Wenn Sie Geld an eine Unterkontoadresse überweisen, erstellt Vertex tatsächlich dieses Unterkonto.
Hierzu muss der Nonce des Accounts abgefragt und als Parameter an die Parameter der Transferschnittstelle übergeben werden.
function main() {
var ret = HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=nonces&address=0x123...")
var obj = JSON.parse(ret)
var nonce = obj["data"]["tx_nonce"]
Log("nonce:", nonce)
var params = {
"transfer_quote": {
"tx": {
// default -> subAcc02
"sender": "0xabc...", // default
"recipient": "0xdef...", // subAcc02
"amount": "7000000000000000000",
"nonce": nonce
}
}
}
return exchange.IO("api", "POST", "https://gateway.prod.vertexprotocol.com/v1/execute", "", JSON.stringify(params))
}
Beispiel: 0xabc… entspricht der Unterkontoadresse mit dem Tag „default“. 0xdef… entspricht der Unterkontoadresse mit dem Tag subAcc02. 0x123… ist die Wallet-Adresse.
function main() {
var ret = HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=nonces&address=0x123...")
var obj = JSON.parse(ret)
var nonce = obj["data"]["tx_nonce"]
Log("nonce:", nonce)
var params = {
"withdraw_collateral": {
"tx": {
"sender": "0xabc...", // default
"productId": 0, // USDC : 0 , precision : 6
"amount": "10000000", // 10 USDC
"nonce": nonce
}
}
}
return exchange.IO("api", "POST", "https://gateway.prod.vertexprotocol.com/v1/execute", "", JSON.stringify(params))
}
Achten Sie auf die Genauigkeit von USDC.
function main() {
var ret = HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=nonces&address=0x123...")
var obj = JSON.parse(ret)
var nonce = obj["data"]["tx_nonce"]
Log("nonce:", nonce)
var params = {
"mint_lp": {
"tx": {
"sender": "0xabc...", // default
"productId": 31, // USDT_USDC
"amountBase": "10000000000000000000",
"quoteAmountLow": "9999900000000000000",
"quoteAmountHigh": "10100000000000000000",
"nonce": nonce,
}
}
}
return exchange.IO("api", "POST", "https://gateway.prod.vertexprotocol.com/v1/execute", "", JSON.stringify(params))
}
Prägen Sie LP-Token für HandelspaareUSDT_USDC
Der Börsenpool sorgt für zusätzliche Liquidität.
function main() {
var ret = HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=nonces&address=0x123...")
var obj = JSON.parse(ret)
var nonce = obj["data"]["tx_nonce"]
Log("nonce:", nonce)
var params = {
"burn_lp": {
"tx": {
"sender": "0xabc...", // default
"productId": 31, // USDT_USDC
"amount": "7500000000000000000",
"nonce": nonce,
}
}
}
return exchange.IO("api", "POST", "https://gateway.prod.vertexprotocol.com/v1/execute", "", JSON.stringify(params))
}
Endpunkt der WebSocket-Schnittstelle:wss://gateway.prod.vertexprotocol.com/v1/ws
。
[🚧🚧🚧ing…]
Die obigen Tests basieren auf dem neuesten Custodian. Sie müssen den neuesten Custodian herunterladen, um den Vertex DEX-Aggregator zu unterstützen.
Vielen Dank für Ihre Unterstützung und fürs Lesen.