[TOC]
Este es el tercer artículo sobre la práctica cuantitativa de los intercambios DEX. Esta vez presentaremos la guía de uso del protocolo Vertex.
En el marco de los intercambios descentralizados tradicionales (DEX), los traders cuantitativos a menudo necesitan llegar a acuerdos: o aceptan el alto deslizamiento y la baja eficiencia de ejecución del modelo de creador de mercado automatizado (AMM), o caen en el dilema técnico de la fragmentación de la liquidez entre cadenas y las funciones derivadas únicas. El surgimiento del Protocolo Vertex está redefiniendo los límites en cadena de las estrategias cuantitativas a través de un experimento de fusión “descentralizado + nivel institucional”; aquí no existe un dilema de “elegir uno de dos”, solo el equilibrio máximo de velocidad, profundidad y libertad.
Como el primer DEX en integrar un fondo de liquidez multicadena unificado, un libro de órdenes híbrido (CLOB) y un mercado de divisas integrado, Vertex toma la “experiencia centralizada, alma descentralizada” como su núcleo y abre una vía única para los traders cuantitativos:
Una nueva definición de velocidad y fluidez
Con la continua evolución de la tecnología blockchain, la frontera entre los intercambios centralizados tradicionales (CEX) y los intercambios descentralizados (DEX) se está difuminando gradualmente. Como centro de la plataforma Vertex, Vertex Edge no solo redefine la velocidad y la liquidez de las transacciones, sino que también combina a la perfección una excelente tecnología de correspondencia de órdenes y ventajas de autocustodia a través de la integración entre cadenas, brindando una nueva experiencia DeFi a los comerciantes globales.
Unificar la liquidez entre cadenas: acabar con la fragmentación de la liquidez En los mercados tradicionales, la liquidez entre diferentes cadenas suele estar fragmentada, lo que provoca que los operadores no puedan disfrutar de los mejores precios y profundidad de transacción. Vertex Edge nació en este contexto, logrando el intercambio sincrónico de liquidez permanente entre múltiples cadenas mediante una red de libro de órdenes unificada. Actualmente, Vertex Edge ha cubierto la liquidez de contratos perpetuos en 7 cadenas principales, incluidas Arbitrum, Base, Sei, Blast, Mantle, Sonic y Abstract, de modo que los comerciantes ya no necesitan preocuparse por la dispersión de la liquidez y pueden comerciar al mejor precio, logrando realmente una conexión perfecta de liquidez global.
Negociación de libros de órdenes híbridos: el equilibrio perfecto entre la conciliación ultrarrápida y la liquidación en cadena Vertex Edge adopta un modelo de negociación de libro de órdenes híbrido y sus tecnologías principales incluyen:
Coincidencia de libro de órdenes fuera de cadena: utiliza un mecanismo de coincidencia fuera de cadena de velocidad ultra alta para lograr la coincidencia de órdenes con una latencia de solo 5 a 15 milisegundos, comparable a la mayoría de los intercambios centralizados; Motor de riesgo en cadena y AMM: los sistemas de gestión de riesgos y los creadores de mercado automatizados (AMM) se implementan en cada cadena compatible para garantizar que las órdenes puedan liquidarse de manera segura y transparente después de la coincidencia. Esta arquitectura no solo garantiza una respuesta de transacción extremadamente rápida, sino que también brinda a los usuarios seguridad descentralizada a través de la liquidación en cadena, lo que permite a los comerciantes disfrutar de un rendimiento de nivel CEX mientras mantienen la independencia de la autocustodia de los activos.
Función multicuenta: administre múltiples cuentas en una sola billetera y asigne fondos de manera más eficiente; Posiciones spot apalancadas: utilizar todos los activos como margen para lograr una mayor eficiencia de capital; Gestión flexible de riesgos: Los depósitos, posiciones y datos de ganancias y pérdidas se consideran de manera unificada para controlar con precisión la exposición al riesgo.
Dirección de la página de inicio de sesión del “protocolo vertex”:
Vertex es igual que la mayoría de los DEX. Después de iniciar sesión en la aplicación descentralizada, debe conectarse a la billetera para obtener la autorización. El sistema de subcuentas de Vertex se distingue en función de una etiqueta. La etiqueta participa en el cálculo de la dirección de la billetera para obtener una dirección de billetera de subcuenta. Al mismo tiempo, esta dirección está autorizada para realizar pedidos y otras operaciones.
Por ejemplo, utiliceWalletConnectLa dirección de la billetera al conectarse es:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43
, la etiqueta predeterminada es “predeterminada” y la dirección de subcuenta calculada es:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c4364656661756c740000000000
. Las etiquetas predeterminadas son:64656661756c740000000000
。
Vertex admite la recarga de múltiples activos. Generalmente, eliges recargar USDC como margen y usar directamente la billetera conectada para transferir transacciones. Cabe señalar que operaciones como retirar, transferir, enviar tokens y transferir subcuentas en Vertex consumirán USDC y las tarifas no son bajas, por lo que estas operaciones deben realizarse con precaución.
Cambiar a una cadena diferente:
En Vertex, las diferentes cadenas tienen información de configuración diferente, como nodos, indexadores e identificadores de cadena. La cadena predeterminada para la encapsulación FMZ esArbitrum One
Se puede usar.Log(HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=contracts"))
Consultar el ID de una cadena, información del contrato implementado, etc.
Después de iniciar sesión en FMZ.COM, en la página de configuración de la bolsa, seleccione “Criptomoneda”, seleccione Vertex Exchange, puede configurar directamente la clave de proxy de la billetera en la aplicación descentralizada. Por supuesto, también puede configurar la clave privada de la billetera. En Vertex, puede usar la interfaz para administrar la autorización/desautorización de la clave de proxy y otras operaciones, lo que también es más conveniente.
Clave de proxy:
Por ejemplo, en la página de inicio del intercambio DEX de vértices: navegador Chrome (activar depuración) -> Aplicación -> Almacenamiento local -> https://app.vertex -> vertex userSettings
Configurar Vertex Exchange
Hay dos cosas que se deben configurar en FMZ. La primera es la dirección de la billetera (no la dirección de la clave proxy utilizada para firmar, debe ser la dirección de la billetera conectada a la aplicación descentralizada). La segunda es la clave secreta utilizada para firmar (puede ser una clave privada de billetera o una clave de proxy). Dado que se pueden usar claves proxy, la dirección de billetera configurada y la clave no son necesariamente un par.
El sistema de subcuentas de Vertex se identifica mediante etiquetas. La etiqueta predeterminada que se utiliza en FMZ esdefault
La cuenta principal de la etiqueta, si necesitas cambiarla, puedes usarla en el código:
exchange.IO("subAccountTag", "default") // 切换到主子账号
exchange.IO("subAccountTag", "test01") // 切换到标签名为 test01 的子账号
Después de configurar la información de configuración de intercambio e implementar un programa de custodia que pueda acceder a la interfaz de vértice, podemos comenzar a escribir algo de código para operaciones prácticas.
Usamos la subcuenta principal para realizar pruebas (la subcuenta con etiqueta: predeterminada) y usamosArbitrumred.
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
}
Se puede ver que el tipo de contrato en Vertex es un contrato basado en USDC, el margen es USDC y el valor de un contrato representa una moneda correspondiente, por ejemploBTC_USDC.swap
Es decir, el contrato de BTC basado en USDC, un contrato representa una posición de BTC. El código anterior muestra cómo solicitar información del mercado de contratos y generar diversos contenidos.
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()
})
}
Diagrama de vértices
Dibujo de la operación estratégica de FMZ
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) + "`")
}
El ciclo de la tasa de financiación es de 1 hora.
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")
}
Los datos devueltos por la solicitud final son:{"status":"success","data":{"max_order_size":"170536415320344899"},"request_type":"query_max_order_size"}
Se puede ver que los activos disponibles en la cuenta actual para el contrato perpetuo de Ethereum con un precio de 3000, la cantidad máxima de pedido para una orden de venta es: 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")
}
Información de autorización encontrada:
{“status”:“success”,“data”:{“linked_signer”:“0x79119…”},“request_type”:“query_linked_signer”} La dirección “0x79119…” es la dirección proxy para autorizar transacciones de órdenes cuando se conecta a la billetera en la página de inicio de Vertex. Esta autorización puede ser revocada o agregada (a través de llamadas API).
El siguiente es el objetivo de este artículo. Hemos estado ocupados durante mucho tiempo simplemente para realizar transacciones de manera simple y rápida en intercambios descentralizados.
Pruebe una operación más sencilla y coloque una orden límite normal.
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) + "`")
}
Cabe señalar que los datos proporcionados por la API de Vertex difieren del contenido que se muestra en la página de inicio de Vertex, principalmente debido a las diferencias en el precio promedio de las tenencias y las ganancias y pérdidas de las tenencias. Esto se ha enviado al equipo de Vertex y es posible que se actualice más adelante.
4、Trigger Order
Dado que el orden de activación del vértice es independiente del punto final,exchange.IO
Al realizar un pedido condicional para una función, debe especificarTrigger: https://trigger.prod.vertexprotocol.com
, continuemos con la operación práctica.
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))
}
Debajo del punto final del disparador también hay:
El método de llamada es similar a Colocar orden de activación, por lo que no entraré en detalles aquí.
La etiqueta de subcuenta predeterminada es:default
, cambiamos a una etiqueta personalizada:subAcc02
。
function main() {
exchange.IO("subAccountTag", "subAcc02")
return exchange.GetAccount()
}
Al transferir dinero a una dirección de subcuenta, Vertex creará dicha subcuenta.
Es necesario consultar el nonce de la cuenta y pasarlo a los parámetros de la interfaz de transferencia como un parámetro.
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))
}
Por ejemplo: 0xabc… corresponde a la dirección de subcuenta con la etiqueta predeterminada. 0xdef… corresponde a la dirección de subcuenta con etiqueta subAcc02. 0x123… es la dirección de la billetera.
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))
}
Preste atención a la precisión del 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))
}
Acuñar tokens LP para intercambiar paresUSDT_USDC
El pool de intercambio agrega liquidez.
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))
}
Punto final de la interfaz WebSocket:wss://gateway.prod.vertexprotocol.com/v1/ws
。
[🚧🚧🚧ing…]
Las pruebas anteriores se basan en el custodio más reciente. Debe descargar el custodio más reciente para admitir el agregador Vertex DEX.
Gracias por su apoyo y gracias por leer.