send indicative quotes to mainnet (#374)

* Bumping drift-common to ab538e0c1efbf64a3dfecf2af16e5a75aab81400

* Bumping drift-common to cf7f6ec63febe0d3b661f187e4e26e729797c4d0

* Bumping drift-common to 149f5efe5444d89b53b5370dcea4a3115fec8c5f

* Bumping drift-common to c879f8a85bfcbaef1f1c6d9c6bf4a05e8970fa0a

* Bumping drift-common to d089c9ed7e7400a0f3ea98a0184a4e3bf273fcf5

* dlob add fetch indicative quotes (#372)

* dlob add fetch indicative quotes

* indicative ws stream

* prettify

* allow for oracle orders

* Bumping drift-common to 56331c89a2285a04cc86a639e0fceeda03366f43

* add console log for debugging indicative

* add indicative in l2 queries

* add more console logging for debugging

* bump common and remove logging

* Bumping drift-common to 43104f473f43111f8cc34733a43a85b5fef7f778

* Bumping drift-common to 6d75612fa1fab858daa90cdb91f0c8c9edbc8242

* Bumping drift-common to 3a42e9665c04a27bcf92e7faa50c168690312880

* Bumping drift-common to 20351d45f2644fb7194ffce441d3d2cb8d6c6b4b

* Bumping drift-common to 04216dfc03aa659db24fc24ba42aa8a4e9a8bb9a

* Bumping drift-common to ad20bbe9d3a262c547f66ec464306fabac539fd8

* Bumping drift-common to 5539ad5f3849b19e1b7106f783a16a182fc9a411

* Bumping drift-common to 8b7e118f1aed9d1d7a786cd165f0ceef2a07297c

* Bumping drift-common to 52b7948cebb0ed6bc1f8278b0f549366a1be3ba0

* Bumping drift-common to 26a603c2d78f7f662cb872075bdff1fd6b75ec43

* Bumping drift-common to 683bfc5cefe5097a257511507f22831f185f1549

* Bumping drift-common to b66eaade382a58b563fdc5ee6c03bc98e5bb2195

* Bumping drift-common to 9a48bea13265723c5d17377e68aaf9984b24c722

* Bumping drift-common to a147ab129f6eb59d77889ac2b7a915ca910d83dd

* Bumping drift-common to 65891abfcd5f59c726aecb211ae77ca38394bdf1

* Bumping drift-common to 540cdbbc9b322990d288af8f4f3183f2c96087b7

* Bumping drift-common to 978b8a03b59d0dc24d1269f319ff6a7ff711775a

* Bumping drift-common to af74d01953db3683bca585c2111910cbbe171a72

* Bumping drift-common to cd684e22082438f0cb784ec234fd9e5d3cd63bb2

---------

Co-authored-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
moosecat
2025-04-28 10:16:44 -07:00
committed by GitHub
parent 7e2ae36ee9
commit a55be980fe
8 changed files with 422 additions and 271 deletions

View File

@@ -1,11 +1,17 @@
import {
BN,
DLOBSubscriber,
DLOBSubscriptionConfig,
DriftEnv,
L2OrderBookGenerator,
MarketType,
Order,
OrderStatus,
OrderTriggerCondition,
OrderType,
PerpOperation,
PositionDirection,
ZERO,
isOperationPaused,
isVariant,
} from '@drift-labs/sdk';
@@ -37,6 +43,8 @@ const PERP_MAKRET_STALENESS_THRESHOLD = 30 * 60 * 1000;
const SPOT_MAKRET_STALENESS_THRESHOLD = 60 * 60 * 1000;
const STALE_ORACLE_REMOVE_VAMM_THRESHOLD = 160;
const INDICATIVE_QUOTES_PUBKEY = 'inDNdu3ML4vG5LNExqcwuCQtLcCU8KfK5YM2qYV3JJz';
const PERP_MARKETS_TO_SKIP_SLOT_CHECK =
process.env.PERP_MARKETS_TO_SKIP_SLOT_CHECK !== undefined
? parsePositiveIntArray(process.env.PERP_MARKETS_TO_SKIP_SLOT_CHECK)
@@ -55,6 +63,7 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
public marketArgs: wsMarketArgs[] = [];
public lastSeenL2Formatted: Map<MarketType, Map<number, any>>;
redisClient: RedisClient;
indicativeQuotesRedisClient?: RedisClient;
public killSwitchSlotDiffThreshold: number;
public lastMarketSlotMap: Map<
MarketType,
@@ -65,6 +74,7 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
config: DLOBSubscriptionConfig & {
env: DriftEnv;
redisClient: RedisClient;
indicativeQuotesRedisClient?: RedisClient;
perpMarketInfos: wsMarketInfo[];
spotMarketInfos: wsMarketInfo[];
spotMarketSubscribers: SubscriberLookup;
@@ -73,6 +83,8 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
) {
super(config);
this.redisClient = config.redisClient;
this.indicativeQuotesRedisClient = config.indicativeQuotesRedisClient;
this.killSwitchSlotDiffThreshold =
config.killSwitchSlotDiffThreshold || 200;
@@ -124,6 +136,105 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
await super.updateDLOB();
for (const marketArgs of this.marketArgs) {
try {
if (this.indicativeQuotesRedisClient) {
const marketType = isVariant(marketArgs.marketType, 'perp')
? 'perp'
: 'spot';
const mms = await this.indicativeQuotesRedisClient.smembers(
`market_mms_${marketType}_${marketArgs.marketIndex}`
);
const mmQuotes = await Promise.all(
mms.map((mm) => {
return this.indicativeQuotesRedisClient.get(
`mm_quotes_${marketType}_${marketArgs.marketIndex}_${mm}`
);
})
);
const nowMinus1000Ms = Date.now() - 1000;
mmQuotes.forEach((quote) => {
if (Number(quote['ts']) > nowMinus1000Ms) {
const indicativeBaseOrder: Order = {
status: OrderStatus.OPEN,
orderType: OrderType.LIMIT,
orderId: 0,
slot: new BN(this.slotSource.getSlot()),
marketIndex: marketArgs.marketIndex,
marketType: marketArgs.marketType,
baseAssetAmount: ZERO,
immediateOrCancel: false,
direction: PositionDirection.LONG,
oraclePriceOffset: 0,
maxTs: new BN(quote['ts'] + 1000),
reduceOnly: false,
triggerCondition: OrderTriggerCondition.ABOVE,
price: ZERO,
userOrderId: 0,
postOnly: true,
auctionDuration: 0,
auctionStartPrice: ZERO,
auctionEndPrice: ZERO,
// Rest are not necessary and set for type conforming
existingPositionDirection: PositionDirection.LONG,
triggerPrice: ZERO,
baseAssetAmountFilled: ZERO,
quoteAssetAmountFilled: ZERO,
quoteAssetAmount: ZERO,
bitFlags: 0,
postedSlotTail: 0,
};
if (quote['bid_size'] && quote['bid_price']) {
// Sanity check bid price and size
const indicativeBid: Order = Object.assign(
{},
indicativeBaseOrder,
{
oraclePriceOffset: quote['is_oracle_offset']
? quote['bid_price']
: 0,
price: quote['is_oracle_offset']
? 0
: new BN(quote['bid_price']),
baseAssetAmount: new BN(quote['bid_size']),
direction: PositionDirection.LONG,
}
);
this.dlob.insertOrder(
indicativeBid,
INDICATIVE_QUOTES_PUBKEY,
this.slotSource.getSlot(),
false
);
}
if (quote['ask_size'] && quote['ask_price']) {
const indicativeAsk: Order = Object.assign(
{},
indicativeBaseOrder,
{
oraclePriceOffset: quote['is_oracle_offset']
? quote['ask_price']
: 0,
price: quote['is_oracle_offset']
? 0
: new BN(quote['ask_price']),
baseAssetAmount: new BN(quote['ask_size']),
direction: PositionDirection.SHORT,
}
);
this.dlob.insertOrder(
indicativeAsk,
INDICATIVE_QUOTES_PUBKEY,
this.slotSource.getSlot(),
false
);
}
}
});
}
this.getL2AndSendMsg(marketArgs);
this.getL3AndSendMsg(marketArgs);
} catch (error) {
@@ -162,6 +273,7 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
logger.info('Oracle is stale, removing vamm orders');
includeVamm = false;
}
const l2 = this.getL2({ ...l2FuncArgs, includeVamm });
const slot = l2.slot;
const lastMarketSlotAndTime = this.lastMarketSlotMap
@@ -264,44 +376,43 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
this.redisClient.publish(
`${clientPrefix}orderbook_${marketType}_${marketArgs.marketIndex}${
this.protectedMakerView ? '_pmm' : ''
this.indicativeQuotesRedisClient ? '_indicative' : ''
}`,
l2Formatted
);
this.redisClient.set(
`last_update_orderbook_${marketType}_${marketArgs.marketIndex}${
this.protectedMakerView ? '_pmm' : ''
this.indicativeQuotesRedisClient ? '_indicative' : ''
}`,
l2Formatted_depth100
);
const oraclePriceData =
marketType === 'spot'
? this.driftClient.getOracleDataForSpotMarket(marketArgs.marketIndex)
: this.driftClient.getOracleDataForPerpMarket(marketArgs.marketIndex);
const bids = this.dlob
.getBestMakers({
marketIndex: marketArgs.marketIndex,
marketType: marketArgs.marketType,
direction: PositionDirection.LONG,
slot: slot,
oraclePriceData,
numMakers: 4,
})
.map((x) => x.toString());
const asks = this.dlob
.getBestMakers({
marketIndex: marketArgs.marketIndex,
marketType: marketArgs.marketType,
direction: PositionDirection.SHORT,
slot,
oraclePriceData,
numMakers: 4,
})
.map((x) => x.toString());
this.redisClient.set(
`last_update_orderbook_best_makers_${marketType}_${marketArgs.marketIndex}`,
{ bids, asks, slot }
);
if (!this.indicativeQuotesRedisClient) {
const bids = this.dlob
.getBestMakers({
marketIndex: marketArgs.marketIndex,
marketType: marketArgs.marketType,
direction: PositionDirection.LONG,
slot: slot,
oraclePriceData: oracleData,
numMakers: 4,
})
.map((x) => x.toString());
const asks = this.dlob
.getBestMakers({
marketIndex: marketArgs.marketIndex,
marketType: marketArgs.marketType,
direction: PositionDirection.SHORT,
slot,
oraclePriceData: oracleData,
numMakers: 4,
})
.map((x) => x.toString());
this.redisClient.set(
`last_update_orderbook_best_makers_${marketType}_${marketArgs.marketIndex}`,
{ bids, asks, slot }
);
}
}
getL3AndSendMsg(marketArgs: wsMarketArgs): void {
@@ -355,7 +466,7 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
this.redisClient.set(
`last_update_orderbook_l3_${marketType}_${marketArgs.marketIndex}${
this.protectedMakerView ? '_pmm' : ''
this.indicativeQuotesRedisClient ? '_indicative' : ''
}`,
l3
);