UNPKG

@drift-labs/common

Version:

Common functions for Drift

200 lines 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ORDER_COMMON_UTILS = void 0; const sdk_1 = require("@drift-labs/sdk"); const orders_1 = require("../constants/orders"); const utils_1 = require("../utils"); const trade_1 = require("../constants/trade"); const market_1 = require("./market"); const getOrderLabelFromOrderDetails = (orderDetails) => { var _a; if ((0, utils_1.matchEnum)(orderDetails.orderType, sdk_1.OrderType.MARKET)) return orders_1.UI_ORDER_TYPES.market.label; if ((0, utils_1.matchEnum)(orderDetails.orderType, sdk_1.OrderType.LIMIT)) return `${orderDetails.oraclePriceOffset && !((_a = orderDetails.oraclePriceOffset) === null || _a === void 0 ? void 0 : _a.eqZero()) ? 'Oracle ' : ''}${orders_1.UI_ORDER_TYPES.limit.label}`; if ((0, utils_1.matchEnum)(orderDetails.orderType, sdk_1.OrderType.ORACLE)) return orders_1.UI_ORDER_TYPES.oracle.label; if ((0, utils_1.matchEnum)(orderDetails.orderType, sdk_1.OrderType.TRIGGER_MARKET)) { const isTriggered = (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_ABOVE) || (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_BELOW); if (isTriggered) { return 'Market (Triggered)'; } const isTriggerAbove = (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.ABOVE); const isExistingPositionShort = (0, utils_1.matchEnum)(orderDetails.existingPositionDirection, sdk_1.PositionDirection.SHORT); const isOrderDirectionShort = (0, utils_1.matchEnum)(orderDetails.direction, sdk_1.PositionDirection.SHORT); if (isTriggerAbove) { return isExistingPositionShort ? isOrderDirectionShort ? 'Trigger Market' // trigger above, existing position short, order direction short : orders_1.UI_ORDER_TYPES.stopMarket.label // trigger above, existing position short, order direction long : isOrderDirectionShort ? orders_1.UI_ORDER_TYPES.takeProfitMarket.label // trigger above, existing position long, order direction short : 'Trigger Market'; // trigger above, existing position long, order direction long } else { return isExistingPositionShort ? isOrderDirectionShort ? 'Trigger Market' // trigger below, existing position short, order direction short : orders_1.UI_ORDER_TYPES.takeProfitMarket.label // trigger below, existing position short, order direction long : isOrderDirectionShort ? orders_1.UI_ORDER_TYPES.stopMarket.label // trigger below, existing position long, order direction short : 'Trigger Market'; // trigger below, existing position long, order direction long } } if ((0, utils_1.matchEnum)(orderDetails.orderType, sdk_1.OrderType.TRIGGER_LIMIT)) { const isTriggered = (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_ABOVE) || (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_BELOW); const isTriggerAbove = (0, utils_1.matchEnum)(orderDetails.triggerCondition, sdk_1.OrderTriggerCondition.ABOVE); const isExistingPositionLong = (0, utils_1.matchEnum)(orderDetails.existingPositionDirection, sdk_1.PositionDirection.LONG); const isOrderDirectionLong = (0, utils_1.matchEnum)(orderDetails.direction, sdk_1.PositionDirection.LONG); if (isTriggered) { return 'Limit (Triggered)'; } if (isTriggerAbove) { return isExistingPositionLong ? isOrderDirectionLong ? 'Trigger Limit' // trigger above, existing position long, order direction long : orders_1.UI_ORDER_TYPES.takeProfitLimit.label // trigger above, existing position long, order direction short : isExistingPositionLong ? orders_1.UI_ORDER_TYPES.stopLimit.label // trigger above, existing position short, order direction long : 'Trigger Limit'; // trigger above, existing position short, order direction short } else { return isExistingPositionLong ? isOrderDirectionLong ? 'Trigger Limit' // trigger below, existing position long, order direction long : orders_1.UI_ORDER_TYPES.stopLimit.label // trigger below, existing position long, order direction short : isExistingPositionLong ? orders_1.UI_ORDER_TYPES.takeProfitLimit.label // trigger below, existing position short, order direction long : 'Trigger Limit'; // trigger below, existing position short, order direction short } } return '-'; }; const getLimitPriceFromOracleOffset = (order, oraclePrice) => { if ((order.price && !order.price.eqZero()) || !order.oraclePriceOffset || order.oraclePriceOffset.eqZero() || !oraclePrice || (oraclePrice === null || oraclePrice === void 0 ? void 0 : oraclePrice.eqZero())) { return order.price; } return oraclePrice.add(order.oraclePriceOffset); }; function isAuctionEmpty(auctionParams) { return (auctionParams.auctionStartPrice === trade_1.EMPTY_AUCTION_PARAMS.auctionStartPrice && auctionParams.auctionEndPrice === trade_1.EMPTY_AUCTION_PARAMS.auctionEndPrice && auctionParams.auctionDuration === trade_1.EMPTY_AUCTION_PARAMS.auctionDuration); } const getUIOrderTypeFromSdkOrderType = (orderType, triggerCondition, direction, oracleOffset) => { const isLong = utils_1.ENUM_UTILS.match(direction, sdk_1.PositionDirection.LONG); const triggerAbove = (0, utils_1.matchEnum)(triggerCondition, sdk_1.OrderTriggerCondition.ABOVE) || (0, utils_1.matchEnum)(triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_ABOVE); const triggerBelow = (0, utils_1.matchEnum)(triggerCondition, sdk_1.OrderTriggerCondition.BELOW) || (0, utils_1.matchEnum)(triggerCondition, sdk_1.OrderTriggerCondition.TRIGGERED_BELOW); // Buy side + trigger below: take profit for a short position // Buy side + trigger above: stop loss for a short position // Sell side + trigger above: take profit for a long position // Sell side + trigger below: stop loss for a long position if ((0, utils_1.matchEnum)(orderType, sdk_1.OrderType.MARKET)) { return orders_1.MARKET_ORDER_TYPE_CONFIG; } else if ((0, utils_1.matchEnum)(orderType, sdk_1.OrderType.LIMIT)) { if (oracleOffset && !oracleOffset.eq(sdk_1.ZERO)) { return orders_1.ORACLE_LIMIT_ORDER_TYPE_CONFIG; } else { return orders_1.LIMIT_ORDER_TYPE_CONFIG; } } else if ((0, utils_1.matchEnum)(orderType, sdk_1.OrderType.TRIGGER_MARKET)) { if (isLong) { if (triggerAbove) { return orders_1.STOP_MARKET_ORDER_TYPE_CONFIG; } else if (triggerBelow) { return orders_1.TAKE_PROFIT_MARKET_ORDER_TYPE_CONFIG; } } else { if (triggerAbove) { return orders_1.TAKE_PROFIT_MARKET_ORDER_TYPE_CONFIG; } else if (triggerBelow) { return orders_1.STOP_MARKET_ORDER_TYPE_CONFIG; } } } else if ((0, utils_1.matchEnum)(orderType, sdk_1.OrderType.TRIGGER_LIMIT)) { if (isLong) { if (triggerAbove) { return orders_1.STOP_LIMIT_ORDER_TYPE_CONFIG; } else if (triggerBelow) { return orders_1.TAKE_PROFIT_LIMIT_ORDER_TYPE_CONFIG; } } else { if (triggerAbove) { return orders_1.TAKE_PROFIT_LIMIT_ORDER_TYPE_CONFIG; } else if (triggerBelow) { return orders_1.STOP_LIMIT_ORDER_TYPE_CONFIG; } } } else if ((0, utils_1.matchEnum)(orderType, sdk_1.OrderType.ORACLE)) { return orders_1.ORACLE_MARKET_ORDER_TYPE_CONFIG; } throw new Error('Invalid order type'); }; function getPerpAuctionDuration(priceDiff, price, contractTier) { const percentDiff = priceDiff.mul(sdk_1.PERCENTAGE_PRECISION).div(price); const slotsPerBp = (0, sdk_1.isOneOfVariant)(contractTier, ['a', 'b']) ? new sdk_1.BN(100) : new sdk_1.BN(60); const rawSlots = percentDiff .mul(slotsPerBp) .div(sdk_1.PERCENTAGE_PRECISION.divn(100)); const clamped = sdk_1.BN.min(sdk_1.BN.max(rawSlots, new sdk_1.BN(5)), new sdk_1.BN(180)); return clamped.toNumber(); } /** * Mainly checks if the user will be entering high leverage mode through this order. */ function getPerpOrderParamsBitFlags(marketIndex, driftClient, userAccount, quoteSize, side, enterHighLeverageModeBufferPct = 2) { if (quoteSize.lte(sdk_1.ZERO)) { return undefined; } const { hasHighLeverage: isMarketAHighLeverageMarket } = market_1.MARKET_UTILS.getMaxLeverageForMarket(sdk_1.MarketType.PERP, marketIndex, driftClient); if (!isMarketAHighLeverageMarket) { return undefined; } // Check if user is already in high leverage mode if (userAccount.isHighLeverageMode('Initial')) { return undefined; } // Get max trade size without entering high leverage mode const maxTradeWithoutHLM = userAccount.getMaxTradeSizeUSDCForPerp(marketIndex, side, undefined, false // enterHighLeverageMode = false ); // If order exceeds non-HLM free collateral, enable high leverage mode // if within 2%, also enable high lev mode to avoid failures if (quoteSize.gte(maxTradeWithoutHLM.tradeSize.muln(1 - enterHighLeverageModeBufferPct / 100))) { return sdk_1.OrderParamsBitFlag.UpdateHighLeverageMode; } return undefined; } exports.ORDER_COMMON_UTILS = { getOrderLabelFromOrderDetails, getLimitPriceFromOracleOffset, isAuctionEmpty, getUIOrderTypeFromSdkOrderType, getPerpAuctionDuration, getPerpOrderParamsBitFlags, }; //# sourceMappingURL=order.js.map