Разработка системы управления позициями на perpetual DEX
Perpetual DEX — это dYdX, GMX, Hyperliquid, Gains Network, Vertex. Все они позволяют торговать с плечом без даты экспирации и без CEX кастодии. Но интерфейс большинства из них — это просто UI поверх контрактов. Если нужно управлять позициями программно (бот, vault, протокол автоматизации) — нужна кастомная система.
Управление позицией на perpetual DEX сложнее, чем на спот DEX: позиция имеет состояние (размер, entry price, leverage, margin), изменяется во времени (PnL, funding payments), может быть ликвидирована. Система должна отслеживать всё это в реальном времени и реагировать на пороговые события.
Виды perpetual DEX и их архитектурные отличия
Orderbook-based (dYdX v4, Hyperliquid)
Классический orderbook, но on-chain или в off-chain orderbook с on-chain settlement. dYdX v4 — это отдельный Cosmos appchain, Hyperliquid — собственный L1. Взаимодействие через REST API и WebSocket, аналогично CEX.
Особенность dYdX v4: транзакции отправляются не через Ethereum RPC, а через Cosmos SDK. Другой клиент, другие форматы. @dydxprotocol/v4-client-js — официальный SDK.
Hyperliquid: собственный HTTP API и WebSocket. Подписание через EIP-712 (EVM-совместимо). Наиболее быстрый throughput среди on-chain perps.
AMM-based (GMX v2, Gains Network)
Позиции открываются против liquidity pool, а не counterparty. Price impact есть, orderbook нет. GMX v2 использует синтетические активы через Chainlink price feeds.
GMX v2 контракты: ExchangeRouter для открытия/закрытия позиций, OrderVault для хранения collateral до исполнения. Все операции через createOrder() с параметрами.
Система управления позициями: что входит
Position tracker
Компонент, который непрерывно отслеживает состояние открытых позиций:
interface Position {
id: string;
exchange: "dydx" | "gmx" | "hyperliquid";
market: string; // "ETH-USD"
side: "long" | "short";
size: bigint; // в USD
entryPrice: number;
currentPrice: number;
unrealizedPnl: number;
liquidationPrice: number;
leverage: number;
margin: bigint;
fundingPaid: number; // накопленные funding payments
}
Источники данных: WebSocket подписки на position updates (dYdX, Hyperliquid), polling через REST каждые 5-30 секунд (GMX через subgraph или прямые контракт вызовы).
Risk manager
Следит за приближением к liquidation и executing stop-loss/take-profit:
const riskThresholds = {
liquidationWarning: 0.15, // 15% до ликвидации → алерт
autoReduceAt: 0.10, // 10% до ликвидации → уменьшить позицию
emergencyCloseAt: 0.05, // 5% до ликвидации → закрыть полностью
};
const distanceToLiquidation = (position: Position): number => {
const current = position.currentPrice;
const liq = position.liquidationPrice;
if (position.side === "long") return (current - liq) / current;
return (liq - current) / current;
};
Add margin — первая линия защиты. При приближении к liquidation price — автоматически добавить collateral вместо закрытия позиции. Дешевле по gas и сохраняет позицию. Требует резервного баланса USDC на кошельке.
Partial close — при тяжёлой ситуации уменьшить размер на 30-50%. Снижает размер риска без полного выхода.
Emergency close — полное закрытие рыночным ордером. Высокий slippage, но при реальной угрозе ликвидации — выгоднее потерять 1-2% на slippage, чем 5-15% liquidation penalty.
Funding rate monitor
Funding payments на perpetuals — скрытые издержки, которые при плохом знаке съедают PnL. Отслеживаем:
// Для longs: positive funding rate → вы платите
// Для shorts: positive funding rate → вы получаете
const calculateFundingCost = (
position: Position,
fundingRate8h: number, // например 0.0001 = 0.01%
periods: number
): number => {
const sign = position.side === "long" ? -1 : 1;
return position.size * fundingRate8h * periods * sign;
};
Если накопленный funding cost превышает expected profit по позиции — кандидат на закрытие независимо от PnL.
Интеграция с GMX v2
GMX v2 — самый сложный из популярных perpetual DEX для интеграции, потому что все операции асинхронны через order keeper.
// Открытие long позиции на ETH
IExchangeRouter.CreateOrderParams memory params = IExchangeRouter.CreateOrderParams({
addresses: IExchangeRouter.CreateOrderParamsAddresses({
receiver: address(this),
callbackContract: address(this), // наш контракт получит callback
uiFeeReceiver: address(0),
market: ETH_USD_MARKET,
initialCollateralToken: USDC_ADDRESS,
swapPath: new address[](0)
}),
numbers: IExchangeRouter.CreateOrderParamsNumbers({
sizeDeltaUsd: 10_000 * 1e30, // $10,000 позиция (30 decimals)
initialCollateralDeltaAmount: 1_000 * 1e6, // $1,000 collateral (USDC 6 decimals)
triggerPrice: 0, // market order
acceptablePrice: minAcceptablePrice,
executionFee: executionFee,
callbackGasLimit: 700_000,
minOutputAmount: 0
}),
orderType: Order.OrderType.MarketIncrease,
decreasePositionSwapType: Order.DecreasePositionSwapType.NoSwap,
isLong: true,
shouldUnwrapNativeToken: false,
referralCode: bytes32(0)
});
exchangeRouter.createOrder{value: executionFee}(params);
Ордер исполняется keeper-нодой GMX асинхронно. Callback afterOrderExecution() на вашем контракте сигнализирует об исполнении. Если keeper не исполнил за определённое время — ордер можно отменить через cancelOrder().
Расчёт liquidation price на GMX
// Long:
liq_price = entry_price * (1 - (margin - borrow_fee) / size)
// Short:
liq_price = entry_price * (1 + (margin - borrow_fee) / size)
borrow_fee накапливается со временем — нужно учитывать при расчёте текущего состояния. GMX предоставляет Reader контракт с getPositionInfo() который возвращает актуальные данные включая fees.
Стек и инфраструктура
TypeScript + viem для GMX on-chain взаимодействий. @dydxprotocol/v4-client-js для dYdX. Websocket клиенты для real-time данных. PostgreSQL + TimescaleDB для хранения истории позиций и PnL. Redis для кэширования текущего состояния. Grafana дашборд с метриками по всем открытым позициям.
Ориентиры по срокам
Система трекинга позиций для одного perpetual DEX с алертами — 3-5 дней. Полная система с риск-менеджментом, auto-margin-add и stop-loss/take-profit для одного протокола (GMX или dYdX) — 1-1.5 недели. Мультипротокольная система (GMX + dYdX + Hyperliquid) — 2-3 недели. Стоимость рассчитывается после уточнения целевых бирж и требований к автоматизации.







