Skip to Content
DevelopersDrift SDKMarkets, Oracles, and Positions

Markets, Oracles, and Positions

How it works

Drift has two types of markets: perp markets (perpetual futures with funding rates) and spot markets (token deposits/borrows that serve as collateral). Each market has an onchain account storing configuration like oracle source, fees, funding rates, AMM parameters, and current open interest.

Market Indexes

Markets are identified by a numeric index starting from 0. For example:

  • Perp market 0 is typically SOL-PERP
  • Spot market 0 is typically USDC
  • Perp market 1 might be BTC-PERP, and so on

Where to find market indexes:

  • State account: Query driftClient.getStateAccount() which contains arrays of all perp and spot market configurations
  • SDK methods: Use driftClient.getPerpMarketAccounts() or driftClient.getSpotMarketAccounts() to get all markets and inspect their indexes
  • Market account directly: Each market account has a marketIndex field you can read
  • Symbol lookup: Most bots maintain their own mapping from symbol (e.g., “SOL-PERP”) to market index, or query all markets and build the mapping at startup

Each market integrates with an oracle (usually Pyth or Switchboard) that provides real-time price data. The SDK lets you read oracle prices, check if they’re valid/stale, and use them for quoting or risk calculations. Prices are stored in fixed-point precision (1e6 for PRICE_PRECISION).

Perp markets track funding rates, open interest, and AMM liquidity pools. Spot markets track total deposits, borrows, and utilization rates. When you trade, you’re interacting with these market accounts, opening positions on perp markets or borrowing/depositing in spot markets.

SDK Usage

These are the most common read-path helpers you’ll use to power bots, dashboards, and risk logic.

Market Accounts

Read a single spot market account by index (e.g., market config, oracle source, and utilization state).

const marketIndex = 0; const spotMarket = driftClient.getSpotMarketAccount(marketIndex); console.log(spotMarket?.marketIndex);
Method DriftClient.getSpotMarketAccountReference ↗
ParameterTypeRequired
marketIndex
number
Yes
Returns
SpotMarketAccount | undefined

Read a single perp market account by index (e.g., AMM params, funding state, and open interest).

const marketIndex = 0; const perpMarket = driftClient.getPerpMarketAccount(marketIndex); console.log(perpMarket?.marketIndex);
Method DriftClient.getPerpMarketAccountReference ↗
ParameterTypeRequired
marketIndex
number
Yes
Returns
PerpMarketAccount | undefined

Get all spot market accounts at once, useful for startup symbol/index mapping and dashboards.

const spotMarkets = driftClient.getSpotMarketAccounts(); console.log(spotMarkets.length);
Method DriftClient.getSpotMarketAccountsReference ↗
Returns
SpotMarketAccount[]

Get all perp market accounts at once, useful for scanning market metadata and risk parameters.

const perpMarkets = driftClient.getPerpMarketAccounts(); console.log(perpMarkets.length);
Method DriftClient.getPerpMarketAccountsReference ↗
Returns
PerpMarketAccount[]

Oracle Price

Read the current oracle data for a perp market (price, confidence, and validity flags).

const marketIndex = 0; const oracle = driftClient.getOracleDataForPerpMarket(marketIndex); console.log(oracle.price.toString());
Method DriftClient.getOracleDataForPerpMarketReference ↗
ParameterTypeRequired
marketIndex
number
Yes
Returns
OraclePriceData

Read the current oracle data for a spot market using its market index.

const marketIndex = 0; const oracle = driftClient.getOracleDataForSpotMarket(marketIndex); console.log(oracle.price.toString());
Method DriftClient.getOracleDataForSpotMarketReference ↗
ParameterTypeRequired
marketIndex
number
Yes
Returns
OraclePriceData

Read market-maker-oriented oracle data for perp markets, typically used for DLOB/JIT pricing flows.

const marketIndex = 0; const oracle = driftClient.getMMOracleDataForPerpMarket(marketIndex); console.log(oracle.price.toString());
Method DriftClient.getMMOracleDataForPerpMarketReference ↗
ParameterTypeRequired
marketIndex
number
Yes
Returns
MMOraclePriceData

Positions and Balances

Get your active subaccount’s spot position for a given market index (deposit or borrow state).

const spotPosition = driftClient.getSpotPosition(0); console.log(spotPosition);
Method DriftClient.getSpotPositionReference ↗
ParameterTypeRequired
marketIndex
number
Yes
subAccountId
number
No
Returns
SpotPosition | undefined

Get your active subaccount’s perp position for a given perp market index.

const perpPosition = driftClient.getPerpPosition(0); console.log(perpPosition);
Method DriftClient.getPerpPositionReference ↗
TypeScript docs unavailable for getPerpPosition.

Protocol State

const state = driftClient.getStateAccount(); console.log(state);
Method DriftClient.getStateAccountReference ↗
Returns
StateAccount

Working With the DLOB

The Decentralized Limit Order Book (DLOB) aggregates resting limit orders from all users. If you’re building a market maker, orderbook UI, or matching bot, you’ll want to build a local DLOB by subscribing to orders.

OrderSubscriber

Subscribes to all user orders in real-time via WebSocket or polling. Always needed — this is the raw data source for the DLOB.

import { OrderSubscriber } from "@drift-labs/sdk";
Class OrderSubscriberReference ↗
PropertyTypeRequired
driftClient
DriftClient
Yes
usersAccounts
Map<string, { slot: number; userAccount: UserAccount; }>
Yes
subscription
PollingSubscription | WebsocketSubscription | grpcSubscription
Yes
commitment
Commitment
Yes
eventEmitter
StrictEventEmitter<EventEmitter, OrderSubscriberEvents>
Yes
fetchPromise
Promise<void>
No
fetchPromiseResolver
() => void
Yes
mostRecentSlot
number
Yes
decodeFn
(name: string, data: Buffer) => UserAccount
Yes
decodeData
boolean
No
fetchAllNonIdleUsers
boolean
No
subscribe
() => Promise<void>
Yes
fetch
() => Promise<void>
Yes
tryUpdateUserAccount
(key: string, dataType: "raw" | "decoded" | "buffer", data: UserAccount | Buffer | string[], slot: number) => void
Yes
createDLOB
(protectedMakerParamsMap?: ProtectMakerParamsMap | undefined) => DLOB
Creates a new DLOB for the order subscriber to fill. This will allow a caller to extend the DLOB Subscriber with a custom DLOB type.
Yes
getDLOB
(slot: number, protectedMakerParamsMap?: ProtectMakerParamsMap | undefined) => Promise<DLOB>
Yes
getSlot
() => number
Yes
addPubkey
(userAccountPublicKey: PublicKey) => Promise<void>
Yes
mustGetUserAccount
(key: string) => Promise<UserAccount>
Yes
unsubscribe
() => Promise<void>
Yes

DLOBSubscriber

Builds and maintains an aggregated orderbook from the order stream. Use when you need a continuously-updated L2/L3 orderbook view.

import { DLOBSubscriber } from "@drift-labs/sdk";
Class DLOBSubscriberReference ↗
PropertyTypeRequired
driftClient
DriftClient
Yes
dlobSource
DLOBSource
Yes
slotSource
SlotSource
Yes
updateFrequency
number
Yes
intervalId
Timeout
No
dlob
DLOB
Yes
eventEmitter
StrictEventEmitter<EventEmitter, DLOBSubscriberEvents>
Yes
protectedMakerView
boolean
Yes
subscribe
() => Promise<void>
Yes
getProtectedMakerParamsMap
() => ProtectMakerParamsMap | undefined
Yes
updateDLOB
() => Promise<void>
Yes
getDLOB
() => DLOB
Yes
getL2
({ marketName, marketIndex, marketType, depth, includeVamm, numVammOrders, fallbackL2Generators, latestSlot, }: { marketName?: string; marketIndex?: number; marketType?: MarketType; depth?: number; includeVamm?: boolean; numVammOrders?: number; fallbackL2Generators?: L2OrderBookGenerator[]; latestSlot?: any; }) => L...
Get the L2 order book for a given market.
Yes
getL3
({ marketName, marketIndex, marketType, }: { marketName?: string; marketIndex?: number; marketType?: MarketType; }) => L3OrderBook
Get the L3 order book for a given market.
Yes
unsubscribe
() => Promise<void>
Yes

SlotSubscriber

Tracks the current Solana slot. Needed for timing-sensitive operations like JIT auctions and order expiry.

import { SlotSubscriber } from "@drift-labs/sdk";
Class SlotSubscriberReference ↗
PropertyTypeRequired
connection
any
Yes
currentSlot
number
Yes
subscriptionId
number
Yes
eventEmitter
StrictEventEmitter<EventEmitter, SlotSubscriberEvents>
Yes
timeoutId
Timeout
No
resubTimeoutMs
number
No
isUnsubscribing
boolean
Yes
receivingData
boolean
Yes
subscribe
() => Promise<void>
Yes
updateCurrentSlot
any
Yes
setTimeout
any
Yes
getSlot
() => number
Yes
unsubscribe
(onResub?: boolean | undefined) => Promise<void>
Yes

DLOB

Core data structure with bid/ask sides and query methods. Used internally by DLOBSubscriber; access via dlobSubscriber.getDLOB().

import { DLOB } from "@drift-labs/sdk";
Class DLOBReference ↗
PropertyTypeRequired
openOrders
Map<MarketTypeStr, Set<string>>
Yes
orderLists
Map<MarketTypeStr, Map<number, MarketNodeLists>>
Yes
maxSlotForRestingLimitOrders
number
Yes
initialized
boolean
Yes
protectedMakerParamsMap
ProtectMakerParamsMap
Yes
init
any
Yes
clear
() => void
Yes
initFromUserMap
(userMap: UserMap, slot: number) => Promise<boolean>
initializes a new DLOB instance
Yes
insertOrder
(order: Order, userAccount: string, slot: number, isUserProtectedMaker: boolean, baseAssetAmount: BN, onInsert?: OrderBookCallback | undefined) => void
Yes
insertSignedMsgOrder
(order: Order, userAccount: string, isUserProtectedMaker: boolean, baseAssetAmount?: any, onInsert?: OrderBookCallback | undefined) => void
Yes
addOrderList
(marketType: MarketTypeStr, marketIndex: number) => void
Yes
delete
(order: Order, userAccount: PublicKey, slot: number, isUserProtectedMaker: boolean, onDelete?: OrderBookCallback | undefined) => void
Yes
getListForOnChainOrder
(order: Order, slot: number, isProtectedMaker: boolean) => NodeList<any> | undefined
Yes
updateRestingLimitOrders
(slot: number) => void
Yes
updateRestingLimitOrdersForMarketType
(slot: number, marketTypeStr: MarketTypeStr) => void
Yes
getOrder
(orderId: number, userAccount: PublicKey) => Order | undefined
Yes
findNodesToFill
<T extends MarketType>(marketIndex: number, fallbackBid: any, fallbackAsk: any, slot: number, ts: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, stateAccount: StateAccount, marketAccount: T extends { ...; } ? SpotMarketAccount : PerpMarketAccount) => NodeT...
Yes
getMakerRebate
(marketType: MarketType, stateAccount: StateAccount, marketAccount: SpotMarketAccount | PerpMarketAccount) => { ...; }
Yes
mergeNodesToFill
(restingLimitOrderNodesToFill: NodeToFill[], takingOrderNodesToFill: NodeToFill[]) => NodeToFill[]
Yes
findRestingLimitOrderNodesToFill
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, isAmmPaused: boolean, stateAccount: StateAccount, marketAccount: T extends { ...; } ? SpotMarketAccount : PerpMarketAccount, makerRebateNumerator: number, make...
Yes
findTakingNodesToFill
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, isAmmPaused: boolean, state: StateAccount, marketAccount: T extends { ...; } ? SpotMarketAccount : PerpMarketAccount, fallbackAsk: any, fallbackBid?: any) => N...
Yes
findTakingNodesCrossingMakerNodes
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, takerNodeGenerator: Generator<...>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: T extends { ...; } ? Ora...
Yes
findNodesCrossingFallbackLiquidity
<T extends MarketType>(marketType: T, slot: number, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, nodeGenerator: Generator<DLOBNode, any, any>, doesCross: (nodePrice: any) => boolean, state: StateAccount, marketAccount: T extends { ...; } ? SpotMarketAccount : PerpMarketAccount...
Yes
findExpiredNodesToFill
(marketIndex: number, ts: number, marketType: MarketType, slot?: any) => NodeToFill[]
Yes
findUnfillableReduceOnlyOrdersToCancel
(marketIndex: number, marketType: MarketType, stepSize: BN) => NodeToFill[]
Yes
getTakingBids
<T extends MarketType>(marketIndex: number, marketType: T, slot: number, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
Yes
getTakingAsks
<T extends MarketType>(marketIndex: number, marketType: T, slot: number, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
Yes
signedMsgGenerator
(signedMsgOrderList: NodeList<"signedMsg">, filter: (x: DLOBNode) => boolean) => Generator<DLOBNode, any, any>
Yes
getBestNode
<T extends MarketTypeStr>(generatorList: Generator<DLOBNode, any, any>[], oraclePriceData: T extends "spot" ? OraclePriceData : MMOraclePriceData, slot: number, compareFcn: (bestDLOBNode: DLOBNode, currentDLOBNode: DLOBNode, slot: number, oraclePriceData: T extends "spot" ? OraclePriceData : MMOraclePriceData) => bo...
Yes
getRestingLimitAsks
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
Yes
getRestingLimitBids
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
Yes
getAsks
<T extends MarketType>(marketIndex: number, _fallbackAsk: any, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
This will look at both the taking and resting limit asks
Yes
getBids
<T extends MarketType>(marketIndex: number, _fallbackBid: any, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData, filterFcn?: DLOBFilterFcn | undefined) => Generator<...>
This will look at both the taking and resting limit bids
Yes
findCrossingRestingLimitOrders
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData) => NodeToFill[]
Yes
determineMakerAndTaker
(askNode: DLOBNode, bidNode: DLOBNode) => { takerNode: DLOBNode; makerNode: DLOBNode; } | undefined
Yes
getBestAsk
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData) => any
Yes
getBestBid
<T extends MarketType>(marketIndex: number, slot: number, marketType: T, oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData) => any
Yes
getStopLosses
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
getStopLossMarkets
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
getStopLossLimits
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
getTakeProfits
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
getTakeProfitMarkets
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
getTakeProfitLimits
(marketIndex: number, marketType: MarketType, direction: PositionDirection) => Generator<DLOBNode, any, any>
Yes
findNodesToTrigger
(marketIndex: number, slot: number, triggerPrice: BN, marketType: MarketType, stateAccount: StateAccount) => NodeToTrigger[]
Yes
printTop
(driftClient: DriftClient, slotSubscriber: SlotSubscriber, marketIndex: number, marketType: MarketType) => void
Yes
getDLOBOrders
() => DLOBOrders
Yes
getNodeLists
() => Generator<NodeList<DLOBNodeType>, any, any>
Yes
getL2
<T extends MarketType>({ marketIndex, marketType, slot, oraclePriceData, depth, fallbackL2Generators, }: { marketIndex: number; marketType: T; slot: number; oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData; depth: number; fallbackL2Generators?: L2OrderBookGenerator[]; }) => L2Order...
Get an L2 view of the order book for a given market.
Yes
getL3
<T extends MarketType>({ marketIndex, marketType, slot, oraclePriceData, }: { marketIndex: number; marketType: T; slot: number; oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData; }) => L3OrderBook
Get an L3 view of the order book for a given market. Does not include fallback liquidity sources
Yes
estimateFillExactBaseAmountInForSide
any
Yes
estimateFillWithExactBaseAmount
<T extends MarketType>({ marketIndex, marketType, baseAmount, orderDirection, slot, oraclePriceData, }: { marketIndex: number; marketType: T; baseAmount: BN; orderDirection: PositionDirection; slot: number; oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData; }) => BN
Yes
getBestMakers
<T extends MarketType>({ marketIndex, marketType, direction, slot, oraclePriceData, numMakers, }: { marketIndex: number; marketType: T; direction: PositionDirection; slot: number; oraclePriceData: T extends { spot: unknown; } ? OraclePriceData : MMOraclePriceData; numMakers: number; }) => PublicKey[]
Yes

UserMap

Efficiently tracks and caches multiple user accounts. Useful for bulk operations across many users (e.g., liquidation bots).

import { UserMap } from "@drift-labs/sdk";
Class UserMapReference ↗
PropertyTypeRequired
userMap
any
Yes
driftClient
DriftClient
Yes
eventEmitter
StrictEventEmitter<EventEmitter, UserEvents>
Yes
connection
any
Yes
commitment
any
Yes
includeIdle
any
Yes
filterByPoolId
any
No
additionalFilters
any
No
disableSyncOnTotalAccountsChange
any
Yes
lastNumberOfSubAccounts
any
Yes
subscription
any
Yes
stateAccountUpdateCallback
any
Yes
decode
any
Yes
mostRecentSlot
any
Yes
syncConfig
any
Yes
syncPromise
any
No
syncPromiseResolver
any
Yes
throwOnFailedSync
any
Yes
subscribe
() => Promise<void>
Yes
addPubkey
(userAccountPublicKey: PublicKey, userAccount?: UserAccount | undefined, slot?: number | undefined, accountSubscription?: UserSubscriptionConfig | undefined) => Promise<...>
Yes
has
(key: string) => boolean
Yes
get
(key: string) => User | undefined
gets the User for a particular userAccountPublicKey, if no User exists, undefined is returned
Yes
getWithSlot
(key: string) => DataAndSlot<User> | undefined
Yes
mustGet
(key: string, accountSubscription?: UserSubscriptionConfig | undefined) => Promise<User>
gets the User for a particular userAccountPublicKey, if no User exists, new one is created
Yes
mustGetWithSlot
(key: string, accountSubscription?: UserSubscriptionConfig | undefined) => Promise<DataAndSlot<User>>
Yes
mustGetUserAccount
(key: string) => Promise<UserAccount>
Yes
getUserAuthority
(key: string) => PublicKey | undefined
gets the Authority for a particular userAccountPublicKey, if no User exists, undefined is returned
Yes
getDLOB
(slot: number, protectedMakerParamsMap?: ProtectMakerParamsMap | undefined) => Promise<DLOB>
implements the DLOBSource interface create a DLOB from all the subscribed users
Yes
updateWithOrderRecord
(record: OrderRecord) => Promise<void>
Yes
updateWithEventRecord
(record: any) => Promise<void>
Yes
values
() => IterableIterator<User>
Yes
valuesWithSlot
() => IterableIterator<DataAndSlot<User>>
Yes
entries
() => IterableIterator<[string, User]>
Yes
entriesWithSlot
() => IterableIterator<[string, DataAndSlot<User>]>
Yes
size
() => number
Yes
getUniqueAuthorities
(filterCriteria?: UserAccountFilterCriteria | undefined) => PublicKey[]
Returns a unique list of authorities for all users in the UserMap that meet the filter criteria
Yes
sync
() => Promise<void>
Yes
getFilters
any
Yes
defaultSync
any
Syncs the UserMap using the default sync method (single getProgramAccounts call with filters). This method may fail when drift has too many users. (nodejs response size limits)
Yes
paginatedSync
any
Syncs the UserMap using the paginated sync method (multiple getMultipleAccounts calls with filters). This method is more reliable when drift has many users.
Yes
unsubscribe
() => Promise<void>
Yes
updateUserAccount
(key: string, userAccount: UserAccount, slot: number) => Promise<void>
Yes
updateLatestSlot
(slot: number) => void
Yes
getSlot
() => number
Yes

Setting Up a Local DLOB

import { SlotSubscriber, OrderSubscriber, DLOBSubscriber } from "@drift-labs/sdk"; const slotSubscriber = new SlotSubscriber(connection); await slotSubscriber.subscribe(); const orderSubscriber = new OrderSubscriber({ driftClient, subscriptionConfig: { type: "websocket" }, fastDecode: true, decodeData: true, }); await orderSubscriber.subscribe(); const dlobSubscriber = new DLOBSubscriber({ driftClient, dlobSource: orderSubscriber, slotSource: slotSubscriber, updateFrequency: 1000, }); await dlobSubscriber.subscribe();
Example DLOB setupReference ↗
TypeScript docs unavailable for DLOB setup.

Getting L2 Orderbook Data

Once the DLOB is subscribed, you can query the aggregated L2 orderbook (price levels with cumulative size):

import { MarketType, PRICE_PRECISION, BASE_PRECISION, convertToNumber } from "@drift-labs/sdk"; const dlob = dlobSubscriber.getDLOB(); const marketIndex = 0; // SOL-PERP // For perp markets, use getMMOracleDataForPerpMarket (returns MMOraclePriceData) const oraclePriceData = driftClient.getMMOracleDataForPerpMarket(marketIndex); const slot = slotSubscriber.getSlot(); const l2 = dlob.getL2({ marketIndex, marketType: MarketType.PERP, oraclePriceData, slot, depth: 10, // number of price levels per side }); // l2.bids and l2.asks are arrays of { price: BN, size: BN } console.log("Top bid:", convertToNumber(l2.bids[0].price, PRICE_PRECISION), "size:", convertToNumber(l2.bids[0].size, BASE_PRECISION)); console.log("Top ask:", convertToNumber(l2.asks[0].price, PRICE_PRECISION), "size:", convertToNumber(l2.asks[0].size, BASE_PRECISION));
Example L2 orderbookReference ↗
TypeScript docs unavailable for L2 orderbook.

Getting Best Bid/Ask

For quick access to the best bid and ask prices without fetching the full orderbook:

import { MarketType, PRICE_PRECISION, convertToNumber } from "@drift-labs/sdk"; const dlob = dlobSubscriber.getDLOB(); const marketIndex = 0; const oraclePriceData = driftClient.getMMOracleDataForPerpMarket(marketIndex); const slot = slotSubscriber.getSlot(); // Returns BN | undefined (undefined if no orders on that side) const bestBid = dlob.getBestBid(marketIndex, slot, MarketType.PERP, oraclePriceData); const bestAsk = dlob.getBestAsk(marketIndex, slot, MarketType.PERP, oraclePriceData); if (bestBid && bestAsk) { console.log("Best bid:", convertToNumber(bestBid, PRICE_PRECISION)); console.log("Best ask:", convertToNumber(bestAsk, PRICE_PRECISION)); console.log("Spread:", convertToNumber(bestAsk.sub(bestBid), PRICE_PRECISION)); }
Example Best bid/askReference ↗
TypeScript docs unavailable for Best bid/ask.
Last updated on