Skip to main content
The position calculation utilities provide comprehensive functions for calculating position values, profit and loss, funding payments, and other position-related metrics.

Position Value Functions

calculateBaseAssetValue

Calculates the market value of closing an entire position using AMM reserves.
calculateBaseAssetValue(
  market: PerpMarketAccount,
  userPosition: PerpPosition,
  mmOraclePriceData: MMOraclePriceData,
  useSpread?: boolean,
  skipUpdate?: boolean,
  latestSlot?: BN
): BN
market
PerpMarketAccount
required
The perpetual market account
userPosition
PerpPosition
required
The user’s position
mmOraclePriceData
MMOraclePriceData
required
The oracle price data
useSpread
boolean
default:"true"
Whether to include spread in calculation
skipUpdate
boolean
default:"false"
Whether to skip AMM updates
latestSlot
BN
The latest slot for calculations
return
BN
Base asset value in QUOTE_PRECISION

Usage Example

import { calculateBaseAssetValue } from '@drift-labs/sdk';

const market = driftClient.getPerpMarketAccount(0);
const position = user.getPerpPosition(0);
const oracleData = driftClient.getOracleDataForPerpMarket(0);

const value = calculateBaseAssetValue(
  market,
  position,
  oracleData,
  true // use spread
);

console.log('Position value:', convertToNumber(value, QUOTE_PRECISION));

PnL Calculation Functions

calculatePositionPNL

Calculates position PnL as: BaseAssetAmount * (Avg Exit Price - Avg Entry Price).
calculatePositionPNL(
  market: PerpMarketAccount,
  perpPosition: PerpPosition,
  withFunding?: boolean,
  oraclePriceData: Pick<OraclePriceData, 'price'>
): BN
market
PerpMarketAccount
required
The perpetual market account
perpPosition
PerpPosition
required
The perpetual position
withFunding
boolean
default:"false"
Whether to include unrealized funding payment PnL
oraclePriceData
Pick<OraclePriceData, 'price'>
required
Oracle price data
return
BN
Position PnL in QUOTE_PRECISION

Usage Example

import { calculatePositionPNL } from '@drift-labs/sdk';

const market = driftClient.getPerpMarketAccount(0);
const position = user.getPerpPosition(0);
const oracleData = driftClient.getOracleDataForPerpMarket(0);

// PnL without funding
const pnl = calculatePositionPNL(market, position, false, oracleData);
console.log('PnL:', convertToNumber(pnl, QUOTE_PRECISION));

// PnL with funding
const pnlWithFunding = calculatePositionPNL(market, position, true, oracleData);
console.log('PnL with funding:', convertToNumber(pnlWithFunding, QUOTE_PRECISION));

calculateClaimablePnl

Calculates the claimable (realizable) PnL for a position, accounting for pool limits.
calculateClaimablePnl(
  market: PerpMarketAccount,
  spotMarket: SpotMarketAccount,
  perpPosition: PerpPosition,
  oraclePriceData: Pick<OraclePriceData, 'price'>
): BN
market
PerpMarketAccount
required
The perpetual market account
spotMarket
SpotMarketAccount
required
The spot market account
perpPosition
PerpPosition
required
The perpetual position
oraclePriceData
Pick<OraclePriceData, 'price'>
required
Oracle price data
return
BN
Claimable PnL in QUOTE_PRECISION

Funding Calculation Functions

calculateUnsettledFundingPnl

Returns unsettled funding PnL for a position.
calculateUnsettledFundingPnl(
  market: PerpMarketAccount,
  perpPosition: PerpPosition
): BN
market
PerpMarketAccount
required
The perpetual market account
perpPosition
PerpPosition
required
The perpetual position
return
BN
Unsettled funding PnL in QUOTE_PRECISION

Usage Example

import { calculateUnsettledFundingPnl } from '@drift-labs/sdk';

const market = driftClient.getPerpMarketAccount(0);
const position = user.getPerpPosition(0);

const fundingPnl = calculateUnsettledFundingPnl(market, position);
console.log('Unsettled funding:', convertToNumber(fundingPnl, QUOTE_PRECISION));

calculateFeesAndFundingPnl

Returns total fees and funding PnL for a position.
calculateFeesAndFundingPnl(
  market: PerpMarketAccount,
  perpPosition: PerpPosition,
  includeUnsettled?: boolean
): BN
market
PerpMarketAccount
required
The perpetual market account
perpPosition
PerpPosition
required
The perpetual position
includeUnsettled
boolean
default:"true"
Whether to include unsettled funding
return
BN
Total fees and funding PnL in QUOTE_PRECISION

Price Calculation Functions

calculateBreakEvenPrice

Calculates the break-even price for a position.
calculateBreakEvenPrice(
  userPosition: PerpPosition
): BN
userPosition
PerpPosition
required
The user’s position
return
BN
Break-even price in PRICE_PRECISION (10^6)

Usage Example

import { calculateBreakEvenPrice } from '@drift-labs/sdk';

const position = user.getPerpPosition(0);
const breakEvenPrice = calculateBreakEvenPrice(position);
console.log('Break-even price:', convertToNumber(breakEvenPrice, PRICE_PRECISION));

calculateEntryPrice

Calculates the entry price for a position.
calculateEntryPrice(
  userPosition: PerpPosition
): BN
userPosition
PerpPosition
required
The user’s position
return
BN
Entry price in PRICE_PRECISION (10^6)

calculateCostBasis

Calculates the cost basis for a position.
calculateCostBasis(
  userPosition: PerpPosition,
  includeSettledPnl?: boolean
): BN
userPosition
PerpPosition
required
The user’s position
includeSettledPnl
boolean
default:"false"
Whether to include settled PnL in calculation
return
BN
Cost basis in PRICE_PRECISION (10^10)

Position Status Functions

positionIsAvailable

Checks if a position slot is available (empty and not being liquidated).
positionIsAvailable(
  position: PerpPosition
): boolean
position
PerpPosition
required
The position to check
return
boolean
True if position is available

positionIsBeingLiquidated

Checks if a position is currently being liquidated.
positionIsBeingLiquidated(
  position: PerpPosition
): boolean
position
PerpPosition
required
The position to check
return
boolean
True if position is being liquidated or bankrupt

isEmptyPosition

Checks if a position is empty (no base amount and no open orders).
isEmptyPosition(
  userPosition: PerpPosition
): boolean
userPosition
PerpPosition
required
The position to check
return
boolean
True if position is empty

hasOpenOrders

Checks if a position has open orders.
hasOpenOrders(
  position: PerpPosition
): boolean
position
PerpPosition
required
The position to check
return
boolean
True if position has open orders, bids, or asks

Direction Helper Functions

findDirectionToClose

Determines the direction needed to close a position.
findDirectionToClose(
  userPosition: PerpPosition
): PositionDirection
userPosition
PerpPosition
required
The position to check
return
PositionDirection
SHORT if position is long, LONG if position is short

positionCurrentDirection

Returns the current direction of a position.
positionCurrentDirection(
  userPosition: PerpPosition
): PositionDirection
userPosition
PerpPosition
required
The position to check
return
PositionDirection
LONG if baseAssetAmount >= 0, SHORT otherwise

Usage Example

import {
  findDirectionToClose,
  positionCurrentDirection,
  PositionDirection
} from '@drift-labs/sdk';

const position = user.getPerpPosition(0);
const currentDir = positionCurrentDirection(position);
const closeDir = findDirectionToClose(position);

console.log('Current direction:', currentDir === PositionDirection.LONG ? 'LONG' : 'SHORT');
console.log('Direction to close:', closeDir === PositionDirection.LONG ? 'LONG' : 'SHORT');

Build docs developers (and LLMs) love