Skip to content

Instantly share code, notes, and snippets.

@wphan
Created September 9, 2024 17:39
Show Gist options
  • Save wphan/060279bd2ceb58490d33524030a74a97 to your computer and use it in GitHub Desktop.
Save wphan/060279bd2ceb58490d33524030a74a97 to your computer and use it in GitHub Desktop.
private async init() {
this.userMap = new UserMap({
driftClient: this.driftClient,
subscriptionConfig: {
type: 'websocket',
commitment: 'confirmed',
},
includeIdle: false,
skipInitialLoad: true,
});
await this.userMap.subscribe();
this.userStatsMap = new UserStatsMap(this.driftClient);
await this.userStatsMap.subscribe([]);
this.slotSubscriber = new SlotSubscriber(this.driftClient.connection);
await this.slotSubscriber.subscribe();
this.dlobSubscriber = new DlobSubscriber({
driftClient: this.driftClient,
dlobSubscriberType: DlobSubscriberType.OrderSubscriber,
commitment: 'confirmed',
refreshIntervalMs: 10_000,
});
await this.dlobSubscriber.subscribe();
}
private async getDriftDlob(
marketIndex: number
): Promise<{ l2: L2OrderBook; l3: L3OrderBook }> {
const slot = this.slotSubscriber.getSlot();
const dlob = await this.dlobSubscriber.getDlob(slot);
const oraclePriceData =
this.driftClient.getOracleDataForPerpMarket(marketIndex);
const l2 = dlob.getL2({
marketIndex,
marketType: MarketType.PERP,
oraclePriceData,
depth: 10,
slot,
});
const l3 = dlob.getL3({
marketIndex,
marketType: MarketType.PERP,
oraclePriceData,
slot,
});
return { l2, l3 };
}
private async buildAndSendTakeOrder(
action: 'buy' | 'sell',
driftMarketIndex: number,
driftL3: L3OrderBook,
sizeType: 'min' | 'max', // if min, take the min of minTakerSize and the maker size, if max, take the max of minTakerSize and the maker size
minTakerSize: BN = MIN_TAKER_SIZE
) {
let maker;
if (action === 'buy' && driftL3.asks.length > 0) {
maker = driftL3.asks[0];
} else if (action === 'sell' && driftL3.bids.length > 0) {
maker = driftL3.bids[0];
} else {
logger.warn(
`${messagePrefix} No ${
action === 'buy' ? 'asks' : 'bids'
} available in the order book`
);
return; // Exit the function if there are no orders to match against
}
const makerUser = await this.userMap.mustGet(maker.maker.toBase58());
const makerAccount = makerUser.getUserAccount();
const makerUserStats = await this.userStatsMap.mustGet(
makerAccount.authority.toBase58()
);
const takerReferrerInfo = this.driftClient.getUserStats().getReferrerInfo();
const baseAssetAmount =
sizeType === 'min'
? BN.min(minTakerSize, maker.size)
: BN.max(minTakerSize, maker.size);
logger.info(
`Taking against ${maker.maker.toBase58()}-${
maker.orderId
}: ${action}ing, driftPrice: ${convertToNumber(
maker.price,
PRICE_PRECISION
)}, driftSize: ${convertToNumber(maker.size, BASE_PRECISION)}`
);
const takeIx = await this.driftClient.getPlaceAndTakePerpOrderIx(
{
orderType: OrderType.LIMIT,
price: maker.price,
marketIndex: driftMarketIndex,
baseAssetAmount,
direction:
action === 'buy' ? PositionDirection.LONG : PositionDirection.SHORT,
immediateOrCancel: true,
},
{
maker: maker.maker,
makerStats: makerUserStats.userStatsAccountPublicKey,
makerUserAccount: makerAccount,
},
takerReferrerInfo
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment