PnL & Risk
How it works
Drift calculates your account’s risk using a health metric (0-100) derived from total collateral vs margin requirements. Health 100 = no margin used, health 0 = liquidation eligible.
PnL (Profit and Loss) comes in two forms: unrealized (mark-to-market value of open positions) and realized (settled when positions close). Unrealized PnL is calculated by comparing your position’s entry price to the current oracle price. For perps, you also have funding PnL from periodic funding rate payments between longs and shorts.
Free collateral is the amount of collateral not currently backing positions, it’s what you can withdraw or use to open new positions. Margin requirements increase with position size and vary by market. Leverage is calculated as notional position value divided by total collateral. These metrics update in real-time as prices and positions change.
SDK Usage
These helpers are commonly used for risk checks, dashboards, and liquidation logic.
User health
Return an overall account health score from 0-100, where lower values mean higher liquidation risk.
const user = driftClient.getUser();
const health = user.getHealth(); // returns number 0-100
console.log(health); // e.g. 85 means 85% healthyMethod User.getHealthReference ↗
Method User.getHealthReference ↗| Parameter | Type | Required |
|---|---|---|
perpMarketIndex | number | No |
| Returns |
|---|
number |
Collateral, margin requirement, leverage
Get total account collateral value in quote units (typically USD precision).
import { QUOTE_PRECISION, convertToNumber } from "@drift-labs/sdk";
// getTotalCollateral returns BN in QUOTE_PRECISION (1e6)
// marginCategory defaults to 'Initial'; pass 'Maintenance' for liquidation checks
const total = driftClient.getUser().getTotalCollateral();
console.log(convertToNumber(total, QUOTE_PRECISION)); // e.g. 1500.50 (USD)Method User.getTotalCollateralReference ↗
Method User.getTotalCollateralReference ↗| Parameter | Type | Required |
|---|---|---|
marginCategory | MarginCategory | No |
strict | boolean | No |
includeOpenOrders | boolean | No |
liquidationBuffer | any | No |
perpMarketIndex | number | No |
| Returns |
|---|
BN |
Get the required margin for the account under initial or maintenance rules.
// getMarginRequirement(marginCategory, strict?)
// marginCategory: 'Initial' (for new positions) or 'Maintenance' (for liquidation)
const req = driftClient.getUser().getMarginRequirement('Initial');
console.log(convertToNumber(req, QUOTE_PRECISION)); // USDMethod User.getMarginRequirementReference ↗
Method User.getMarginRequirementReference ↗Signature 1
| Parameter | Type | Required |
|---|---|---|
marginCategory | MarginCategory | Yes |
liquidationBuffer | any | No |
strict | boolean | No |
includeOpenOrders | boolean | No |
enteringHighLeverage | boolean | No |
| Returns |
|---|
BN |
Signature 2
| Parameter | Type | Required |
|---|---|---|
marginCategory | MarginCategoryThe category of margin to calculate ('Initial' or 'Maintenance'). | Yes |
liquidationBuffer | anyOptional buffer amount to consider during liquidation scenarios. | No |
strict | booleanOptional flag to enforce strict margin calculations. | No |
includeOpenOrders | booleanOptional flag to include open orders in the margin calculation. | No |
enteringHighLeverage | booleanOptional flag indicating if the user is entering high leverage mode. | No |
perpMarketIndex | numberOptional index of the perpetual market. Required if marginType is 'Isolated'. | No |
| Returns |
|---|
BN |
Get currently available collateral that can be used for new positions or withdrawals.
const free = driftClient.getUser().getFreeCollateral();
console.log(convertToNumber(free, QUOTE_PRECISION)); // USD availableMethod User.getFreeCollateralReference ↗
Method User.getFreeCollateralReference ↗| Parameter | Type | Required |
|---|---|---|
marginCategory | MarginCategory | No |
enterHighLeverageMode | boolean | No |
perpMarketIndex | number | No |
| Returns |
|---|
BN |
Get current account leverage as a scaled value (convert to human-readable x leverage).
import { TEN_THOUSAND } from "@drift-labs/sdk";
// getLeverage() returns BN scaled by 10000 (e.g. 2x = BN(20000))
const lev = driftClient.getUser().getLeverage();
console.log(lev.toNumber() / TEN_THOUSAND.toNumber()); // e.g. 2.5 (2.5x leverage)Method User.getLeverageReference ↗
Method User.getLeverageReference ↗| Parameter | Type | Required |
|---|---|---|
includeOpenOrders | boolean | No |
perpMarketIndex | number | No |
| Returns |
|---|
BN |
Unrealized PnL
Get unrealized PnL across open positions (optionally including funding effects).
// Returns BN in QUOTE_PRECISION. Positive = profit, negative = loss.
// Pass withWeightMarginCategory to apply asset/liability weights.
const pnl = driftClient.getUser().getUnrealizedPNL(true); // withFunding=true
console.log(convertToNumber(pnl, QUOTE_PRECISION)); // e.g. -25.50 (USD)Method User.getUnrealizedPNLReference ↗
Method User.getUnrealizedPNLReference ↗| Parameter | Type | Required |
|---|---|---|
withFunding | boolean | No |
marketIndex | number | No |
withWeightMarginCategory | MarginCategory | No |
strict | boolean | No |
liquidationBuffer | any | No |
| Returns |
|---|
BN |
Get unrealized funding PnL only, separated from price-movement PnL.
// Funding PnL only (accumulated funding payments)
const fundingPnl = driftClient.getUser().getUnrealizedFundingPNL();
console.log(convertToNumber(fundingPnl, QUOTE_PRECISION)); // USDMethod User.getUnrealizedFundingPNLReference ↗
Method User.getUnrealizedFundingPNLReference ↗| Parameter | Type | Required |
|---|---|---|
marketIndex | number | No |
| Returns |
|---|
BN |
Entry price helper
Compute the effective entry price for a perp position from its cumulative trade data.
import { calculateEntryPrice, PRICE_PRECISION, convertToNumber } from "@drift-labs/sdk";
const position = driftClient.getUser().getPerpPosition(0);
if (position) {
const entryPrice = calculateEntryPrice(position); // BN in PRICE_PRECISION
console.log(convertToNumber(entryPrice, PRICE_PRECISION)); // e.g. 150.25
}Function calculateEntryPriceReference ↗
Function calculateEntryPriceReference ↗| Parameter | Type | Required |
|---|---|---|
userPosition | PerpPosition | Yes |
Precision: PRICE_PRECISION (10^6)
| Returns |
|---|
BN |
Settle perp PnL
Realize and settle a user’s perp PnL for a specific market into spot balances.
const user = driftClient.getUser();
await driftClient.settlePNL(user.userAccountPublicKey, user.getUserAccount(), 0);Method DriftClient.settlePNLReference ↗
Method DriftClient.settlePNLReference ↗| Parameter | Type | Required |
|---|---|---|
settleeUserAccountPublicKey | PublicKey | Yes |
settleeUserAccount | UserAccount | Yes |
marketIndex | number | Yes |
txParams | TxParams | No |
optionalIxs | TransactionInstruction[] | No |
revenueShareEscrowMap | RevenueShareEscrowMap | No |
| Returns |
|---|
Promise<string> |