@@ -1,6 +1,10 @@
|
|||||||
git submodule init
|
git submodule init
|
||||||
git submodule update --recursive
|
git submodule update --recursive
|
||||||
|
|
||||||
|
rm -rf node_modules
|
||||||
|
rm -rf drift-common/protocol/sdk/node_modules
|
||||||
|
rm -rf drift-common/common-ts/node_modules
|
||||||
|
|
||||||
echo "building sdk..."
|
echo "building sdk..."
|
||||||
cd drift-common/protocol/sdk
|
cd drift-common/protocol/sdk
|
||||||
yarn clean && yarn && yarn build && yarn link
|
yarn clean && yarn && yarn build && yarn link
|
||||||
|
|||||||
Submodule drift-common updated: 6721454501...a9b2094da3
@@ -13,7 +13,7 @@ import {
|
|||||||
PerpOperation,
|
PerpOperation,
|
||||||
PositionDirection,
|
PositionDirection,
|
||||||
ZERO,
|
ZERO,
|
||||||
calculateBidAskPrice,
|
calculateAMMBidAskPrice,
|
||||||
getLimitPrice,
|
getLimitPrice,
|
||||||
isOperationPaused,
|
isOperationPaused,
|
||||||
isVariant,
|
isVariant,
|
||||||
@@ -177,9 +177,11 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
|
|||||||
let bestBid = bestDlobBid;
|
let bestBid = bestDlobBid;
|
||||||
let bestAsk = bestDlobAsk;
|
let bestAsk = bestDlobAsk;
|
||||||
if (marketType === 'perp') {
|
if (marketType === 'perp') {
|
||||||
const [bestVammBid, bestVammAsk] = calculateBidAskPrice(
|
const [bestVammBid, bestVammAsk] = calculateAMMBidAskPrice(
|
||||||
this.driftClient.getPerpMarketAccount(marketArgs.marketIndex).amm,
|
this.driftClient.getPerpMarketAccount(marketArgs.marketIndex).amm,
|
||||||
oraclePriceData,
|
this.driftClient.getMMOracleDataForPerpMarket(
|
||||||
|
marketArgs.marketIndex
|
||||||
|
),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const sdkConfig = initialize({ env: process.env.ENV });
|
|||||||
|
|
||||||
const stateCommitment: Commitment = 'confirmed';
|
const stateCommitment: Commitment = 'confirmed';
|
||||||
const serverPort = process.env.PORT || 6969;
|
const serverPort = process.env.PORT || 6969;
|
||||||
export const ORDERBOOK_UPDATE_INTERVAL = 1000;
|
export const ORDERBOOK_UPDATE_INTERVAL = parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 400;
|
||||||
const WS_FALLBACK_FETCH_INTERVAL = ORDERBOOK_UPDATE_INTERVAL * 60;
|
const WS_FALLBACK_FETCH_INTERVAL = ORDERBOOK_UPDATE_INTERVAL * 60;
|
||||||
const useWebsocket = process.env.USE_WEBSOCKET?.toLowerCase() === 'true';
|
const useWebsocket = process.env.USE_WEBSOCKET?.toLowerCase() === 'true';
|
||||||
const hermesUrl = process.env.HERMES_ENDPOINT;
|
const hermesUrl = process.env.HERMES_ENDPOINT;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ const useOrderSubscriber =
|
|||||||
process.env.USE_ORDER_SUBSCRIBER?.toLowerCase() === 'true';
|
process.env.USE_ORDER_SUBSCRIBER?.toLowerCase() === 'true';
|
||||||
|
|
||||||
const ORDERBOOK_UPDATE_INTERVAL =
|
const ORDERBOOK_UPDATE_INTERVAL =
|
||||||
parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 1000;
|
parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 400;
|
||||||
const WS_FALLBACK_FETCH_INTERVAL = 60_000;
|
const WS_FALLBACK_FETCH_INTERVAL = 60_000;
|
||||||
|
|
||||||
const KILLSWITCH_SLOT_DIFF_THRESHOLD =
|
const KILLSWITCH_SLOT_DIFF_THRESHOLD =
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
PERCENTAGE_PRECISION_EXP,
|
PERCENTAGE_PRECISION_EXP,
|
||||||
} from '@drift-labs/sdk';
|
} from '@drift-labs/sdk';
|
||||||
import { RedisClient } from '@drift/common/clients';
|
import { RedisClient } from '@drift/common/clients';
|
||||||
|
import { TradeOffsetPrice } from '@drift/common';
|
||||||
import { logger } from './logger';
|
import { logger } from './logger';
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
import FEATURE_FLAGS from './featureFlags';
|
import FEATURE_FLAGS from './featureFlags';
|
||||||
@@ -746,6 +747,37 @@ export const convertRawL2ToBN = (rawL2: any): L2OrderBook => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps TradeOffsetPrice values to corresponding property names in estimatedPrices object
|
||||||
|
* @param offsetFrom - TradeOffsetPrice type or 'marketBased' or undefined
|
||||||
|
* @returns Property name string for accessing estimatedPrices
|
||||||
|
*/
|
||||||
|
export const mapTradeOffsetPriceToProperty = (
|
||||||
|
offsetFrom: TradeOffsetPrice | 'marketBased' | undefined
|
||||||
|
): string => {
|
||||||
|
switch (offsetFrom) {
|
||||||
|
case 'best':
|
||||||
|
return 'bestPrice';
|
||||||
|
case 'worst':
|
||||||
|
return 'worstPrice';
|
||||||
|
case 'oracle':
|
||||||
|
return 'oraclePrice';
|
||||||
|
case 'mark':
|
||||||
|
return 'markPrice';
|
||||||
|
case 'entry':
|
||||||
|
return 'entryPrice';
|
||||||
|
case 'bestOffer':
|
||||||
|
// For bestOffer, we'll use the best price (could be refined based on direction)
|
||||||
|
return 'bestPrice';
|
||||||
|
case 'marketBased':
|
||||||
|
// Default to mark price for market-based pricing
|
||||||
|
return 'markPrice';
|
||||||
|
default:
|
||||||
|
// Default fallback to mark price
|
||||||
|
return 'markPrice';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get L2 orderbook data and calculate estimated prices
|
* Get L2 orderbook data and calculate estimated prices
|
||||||
* @param driftClient - DriftClient instance
|
* @param driftClient - DriftClient instance
|
||||||
@@ -935,11 +967,18 @@ export const mapToMarketOrderParams = async (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startPriceProperty = mapTradeOffsetPriceToProperty(
|
||||||
|
params.auctionStartPriceOffsetFrom
|
||||||
|
);
|
||||||
|
const startPrice = estimatedPrices[startPriceProperty];
|
||||||
|
|
||||||
processedSlippageTolerance = calculateDynamicSlippage(
|
processedSlippageTolerance = calculateDynamicSlippage(
|
||||||
params.marketIndex,
|
params.marketIndex,
|
||||||
params.marketType,
|
params.marketType,
|
||||||
driftClient,
|
driftClient,
|
||||||
l2Formatted
|
l2Formatted,
|
||||||
|
startPrice,
|
||||||
|
estimatedPrices.worstPrice
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1072,7 +1111,9 @@ export const calculateDynamicSlippage = (
|
|||||||
marketIndex: number,
|
marketIndex: number,
|
||||||
marketType: string,
|
marketType: string,
|
||||||
driftClient: DriftClient,
|
driftClient: DriftClient,
|
||||||
l2Formatted: L2OrderBook
|
l2Formatted: L2OrderBook,
|
||||||
|
startPrice: BN,
|
||||||
|
worstPrice: BN
|
||||||
): number => {
|
): number => {
|
||||||
// Determine if this is a major market (PERP with marketIndex 0, 1, or 2)
|
// Determine if this is a major market (PERP with marketIndex 0, 1, or 2)
|
||||||
const isPerp = marketType.toLowerCase() === 'perp';
|
const isPerp = marketType.toLowerCase() === 'perp';
|
||||||
@@ -1113,17 +1154,28 @@ export const calculateDynamicSlippage = (
|
|||||||
|
|
||||||
let dynamicSlippage = baseSlippage + spreadBaseSlippage;
|
let dynamicSlippage = baseSlippage + spreadBaseSlippage;
|
||||||
|
|
||||||
|
// use halfway to worst price as size adjusted slippage
|
||||||
|
if (startPrice && worstPrice) {
|
||||||
|
const sizeAdjustedSlippage =
|
||||||
|
(startPrice.sub(worstPrice).abs().toNumber() /
|
||||||
|
BN.max(startPrice, worstPrice).toNumber() /
|
||||||
|
2) *
|
||||||
|
100;
|
||||||
|
|
||||||
|
dynamicSlippage = Math.max(dynamicSlippage, sizeAdjustedSlippage);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply multiplier from env var
|
// Apply multiplier from env var
|
||||||
const multiplier = isMajor
|
const multiplier = isMajor
|
||||||
? parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_MAJOR || '1.02')
|
? parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_MAJOR || '1.02')
|
||||||
: parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_NON_MAJOR || '1.5');
|
: parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_NON_MAJOR || '1.4');
|
||||||
dynamicSlippage = dynamicSlippage * multiplier;
|
dynamicSlippage = dynamicSlippage * multiplier;
|
||||||
|
|
||||||
// Enforce minimum and maximum limits from env vars
|
// Enforce minimum and maximum limits from env vars
|
||||||
const minSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MIN || '0.05'); // 0.05% minimum
|
const minSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MIN || '0.05'); // 0.05% minimum
|
||||||
const maxSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MAX || '5'); // 5% maximum
|
const maxSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MAX || '5'); // 5% maximum
|
||||||
|
|
||||||
return Math.min(Math.max(dynamicSlippage, minSlippage), maxSlippage);
|
return Math.min(Math.max(dynamicSlippage, minSlippage), maxSlippage) / 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user