[TOC]
Это третья статья о количественной практике бирж DEX. На этот раз мы представим руководство по использованию протокола Vertex.
В рамках традиционных децентрализованных бирж (DEX) количественным трейдерам часто приходится идти на компромисс: либо смириться с высоким проскальзыванием и низкой эффективностью исполнения модели автоматизированного маркет-мейкера (AMM), либо столкнуться с технической дилеммой фрагментации ликвидности между цепочками и отдельными производными функциями. Появление Vertex Protocol переопределяет границы количественных стратегий в рамках блокчейна посредством эксперимента по слиянию «децентрализованный + институциональный уровень» — здесь нет дилеммы «выбрать одно из двух», только окончательный баланс скорости, глубины и свободы.
Будучи первой DEX, интегрирующей единый многоцепочечный пул ликвидности, гибридную книгу заказов (CLOB) и встроенный валютный рынок, Vertex берет за основу «централизованный опыт, децентрализованную душу» и открывает уникальный путь для количественных трейдеров:
Новое определение скорости и плавности
С непрерывным развитием технологии блокчейн граница между традиционными централизованными биржами (CEX) и децентрализованными биржами (DEX) постепенно стирается. Vertex Edge, являясь центром платформы Vertex, не только меняет скорость транзакций и ликвидность, но и идеально сочетает в себе превосходную технологию сопоставления ордеров и преимущества самостоятельного хранения за счет кросс-чейн-интеграции, предоставляя трейдерам со всего мира новый опыт DeFi.
Объединение кросс-чейн ликвидности: устранение фрагментации ликвидности На традиционных рынках ликвидность между различными цепочками часто фрагментирована, в результате чего трейдеры не могут воспользоваться лучшими ценами и глубиной транзакций. Vertex Edge появился в этом контексте, реализуя синхронное распределение постоянной ликвидности между несколькими цепочками через единую сеть книг заказов. В настоящее время Vertex Edge охватывает бессрочную контрактную ликвидность на 7 основных цепочках, включая Arbitrum, Base, Sei, Blast, Mantle, Sonic и Abstract, так что трейдерам больше не нужно беспокоиться о дисперсии ликвидности, и они могут торговать по лучшей цене, действительно достигая бесперебойного подключения к глобальной ликвидности.
Гибридная торговля по книге заявок: идеальный баланс между сверхбыстрым сопоставлением и расчетами по цепочке Vertex Edge использует гибридную модель торговли на основе книги ордеров, а ее основные технологии включают в себя:
Оффчейн-сопоставитель книг заказов: использует сверхскоростной оффчейн-механизм сопоставления для достижения сопоставления заказов с задержкой всего 5–15 миллисекунд, что сопоставимо с большинством централизованных бирж; Механизм управления рисками в цепочке и AMM: системы управления рисками и автоматизированные маркет-мейкеры (AMM) развернуты в каждой поддерживаемой цепочке, чтобы гарантировать, что заказы могут быть выполнены безопасным и прозрачным образом после сопоставления. Такая архитектура не только обеспечивает чрезвычайно быстрый отклик на транзакции, но и предоставляет пользователям децентрализованную безопасность за счет расчетов в цепочке, позволяя трейдерам наслаждаться производительностью уровня CEX, сохраняя при этом независимость самостоятельного хранения активов.
Функция нескольких счетов: управляйте несколькими счетами в одном кошельке и распределяйте средства более эффективно; Спотовые позиции с использованием заемных средств: используйте все активы в качестве маржи для достижения более высокой эффективности капитала; Гибкое управление рисками: данные о депозитах, позициях, прибылях и убытках рассматриваются единообразно для точного контроля подверженности риску.
Адрес страницы входа в «протокол вершин»:
Vertex такой же, как и большинство DEX. После входа в dapp вам необходимо подключиться к кошельку для авторизации. Система субсчетов Vertex отличается на основе метки. Метка участвует в расчете адреса кошелька для получения адреса кошелька субсчета. В то же время этот адрес авторизован для размещения заказов и других операций.
Например, используйтеWalletConnectАдрес кошелька при подключении:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43
, метка по умолчанию — «default», а вычисленный адрес субсчета — это:0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c4364656661756c740000000000
. Теги по умолчанию:64656661756c740000000000
。
Vertex поддерживает пополнение нескольких активов. Обычно вы выбираете пополнение USDC в качестве маржи и напрямую используете подключенный кошелек для передачи транзакций. Следует отметить, что такие операции, как снятие, перевод, отправка токенов и перевод субсчетов на Vertex, будут потреблять USDC, а комиссии за них не низкие, поэтому к этим операциям следует относиться с осторожностью.
Переключиться на другую цепочку:
На вершине разные цепи имеют различную информацию о конфигурации, такую как узлы, индексаторы и идентификаторы цепей. Цепь по умолчанию для инкапсуляции FMZ — этоArbitrum One
, можно использоватьLog(HttpQuery("https://gateway.prod.vertexprotocol.com/v1/query?type=contracts"))
Запрос идентификатора цепочки, информации о развернутом контракте и т. д.
После входа на FMZ.COM, на странице конфигурации биржи выберите “Криптовалюта”, выберите Vertex Exchange, вы можете напрямую настроить ключ прокси-кошелька в dapp. Конечно, вы также можете настроить закрытый ключ кошелька. На Vertex вы можете использовать интерфейс для управления авторизацией/деавторизацией ключа прокси и другими операциями, что также более удобно.
Прокси-ключ:
Например, на странице интерфейса биржи Vertex DEX: Браузер Chrome (включить отладку) -> Приложение -> Локальное хранилище -> https://app.vertex -> Vertex userSettings
Настроить обмен вершинами
На FMZ необходимо настроить две вещи. Первая — адрес кошелька (не адрес прокси-ключа, используемого для подписи, это должен быть адрес кошелька, подключенного к dapp). Второй — секретный ключ, используемый для подписи (это может быть закрытый ключ кошелька или прокси-ключ). Поскольку можно использовать прокси-ключи, настроенный адрес кошелька и ключ не обязательно являются парой.
Система субсчетов Vertex идентифицируется тегами. Тег по умолчанию, используемый в FMZ, этоdefault
Основной аккаунт тега, если нужно переключить, можно использовать в коде:
exchange.IO("subAccountTag", "default") // 切换到主子账号
exchange.IO("subAccountTag", "test01") // 切换到标签名为 test01 的子账号
После настройки информации о конфигурации обмена и развертывания программы-хранителя, которая может получить доступ к интерфейсу вершин, мы можем приступить к написанию кода для практических операций.
Мы используем основную субучетную запись для тестирования (субучетную запись с тегом: default), и мы используемArbitrumсеть.
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
}
Видно, что тип контракта на Vertex — контракт на основе USDC, маржа — USDC, а стоимость контракта представляет собой соответствующую валюту, напримерBTC_USDC.swap
То есть, контракт BTC на основе USDC, один контракт представляет позицию BTC. Приведенный выше код показывает, как запрашивать информацию о рынке контрактов и выводить различное содержимое.
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()
})
}
Вершинная диаграмма
Стратегия ФМЗ, операционный чертеж
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) + "`")
}
Цикл ставки финансирования составляет 1 час.
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")
}
Данные, возвращаемые финальным запросом:{"status":"success","data":{"max_order_size":"170536415320344899"},"request_type":"query_max_order_size"}
Видно, что на текущем счете доступны активы для бессрочного контракта Ethereum с ценой 3000, максимальный объем ордера для ордера на продажу составляет: 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")
}
Найдена информация об авторизации:
{“status”:“success”,“data”:{“linked_signer”:“0x79119…”},“request_type”:“query_linked_signer”} Адрес «0x79119…» — это прокси-адрес для авторизации транзакций заказов при подключении к кошельку на странице интерфейса Vertex. Эту авторизацию можно отозвать или добавить (через вызовы API).
Ниже приведено основное содержание статьи. Мы долгое время были заняты только тем, чтобы проводить транзакции просто и быстро на децентрализованных биржах.
Протестируйте более простую сделку и разместите обычный лимитный ордер.
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) + "`")
}
Следует отметить, что данные, предоставляемые API Vertex, отличаются от содержимого, отображаемого на странице интерфейса Vertex, в основном из-за различий в средней цене владения и прибылях и убытках владений. Это было передано обратно команде Vertex и может быть обновлено и дополнено позже.
4、Trigger Order
Поскольку порядок срабатывания вершины не зависит от конечной точки, при использованииexchange.IO
При оформлении условного заказа на функцию необходимо указатьTrigger: https://trigger.prod.vertexprotocol.com
, давайте продолжим практическую работу.
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))
}
Под конечной точкой триггера также находятся:
Метод вызова аналогичен Place Trigger Order, поэтому я не буду здесь вдаваться в подробности.
Тег субсчета по умолчанию:default
, мы переключаемся на пользовательский тег:subAcc02
。
function main() {
exchange.IO("subAccountTag", "subAcc02")
return exchange.GetAccount()
}
При переводе денег на адрес субсчета Vertex фактически создает этот субсчет.
Необходимо запросить одноразовый номер учетной записи и передать его в параметры интерфейса передачи в качестве параметра.
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))
}
Например: 0xabc… соответствует адресу субсчета с тегом default. 0xdef… соответствует адресу субсчета с тегом subAcc02. 0x123… — адрес кошелька.
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))
}
Обратите внимание на точность 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))
}
Выпускать токены LP для торговых парUSDT_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 = {
"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))
}
Конечная точка интерфейса WebSocket:wss://gateway.prod.vertexprotocol.com/v1/ws
。
[🚧🚧🚧ing…]
Вышеуказанные тесты основаны на последнем кастодиане. Вам необходимо загрузить последний кастодиан для поддержки агрегатора Vertex DEX.
Спасибо за вашу поддержку и спасибо за чтение.