Skip to main content
The SDK exports utility functions for position math, TP/SL calculations, fee estimation, order classification, and formatting. These are stateless pure functions — they do not call the API.

Position Calculations

calculatePositionSize

Calculate position size from margin, leverage, and price.

calculateNotionalValue

calculateUnrealizedPnl

calculateRoe

Return on equity (PnL / margin).

calculateRequiredMargin

calculateRealizedPnlPercent

effectiveLeverage

Effective leverage of an open position (positionValueUsd / marginUsd); 0 when margin is zero. Takes a single params object.

liquidationDistancePercent

Absolute distance from the current price to the liquidation price, as a percentage of the current price; 0 when the current price is zero.

removableIsolatedMargin

Calculate the exact margin that can be removed from an isolated position using the provider’s retained-margin requirement. The result includes unrealized PnL and snaps down to the venue’s accepted amount increment. Cross-margined positions and markets whose positionMarginAdjustment is NONE or ADD_ONLY return '0'.
Throws PerpsError with ValidationError for malformed, non-positive, or inconsistent risk inputs.

Position Math (Predictive)

Pure-function helpers for predicting how a perp position changes after a fill — used by add-to-position and partial-close preview blocks. These read SDK shapes as plain numbers (callers parse Position.size, entryPrice, etc. from string), and use the convention long = +1, short = -1. Sizes passed in are non-negative magnitudes; direction is carried by isLong.

directionSign

Direction sign for a position.
Returns: 1 | -1

estimateIsolatedLiquidationPrice

Estimated liquidation price for a new isolated-margin position, parameterised by the venue’s maintenance margin rate. Returns undefined when the inputs cannot produce one (zero leverage, degenerate denominator). For existing positions, prefer Position.liquidationPrice from the venue.
Returns: number | undefined

predictAverageEntryPrice

Predicted average entry price after adding to an existing position. Weighted average of current entry and the new fill price, weighted by leg size in coin units. Both legs must be in the same direction (this helper is for adding to, not flipping, a position).
Returns: number | undefined — the new weighted-average entry price, or undefined if the inputs cannot produce a valid average (zero combined size, non-finite values).

predictNewLeverage

Predicted effective leverage (totalNotional / totalMargin) after adding margin and notional. The caller computes notional from size and price (e.g. with calculateNotionalValue) and supplies the additional margin the user is about to put up.
Returns: number | undefined — the new effective leverage, or undefined if total margin is non-positive.

predictUnrealizedPnl

Predicted unrealised PnL at the current mark price: (markPrice - entryPrice) * size * directionSign(isLong).
Returns: number

realizedPnlOnClose

Realised PnL on the portion of a position being closed: (closePrice - entryPrice) * closeSize * directionSign(isLong).
Returns: number

Order Math (Expected rPnL Previews)

Helpers for previewing the realised PnL the user would lock in if a resting order filled against a matching position. Used by Orders-tab rows on the trading UI. These compose directionSign and realizedPnlOnClose from Position Math, so the two modules stay in lockstep. Orders that open or add to a position have no defined rPnL and return null (typically rendered as an em-dash in the UI).

findMatchingPosition

Pick the matching open position for an order’s asset, if any.
Returns: Position | undefined

resolveCloseSize

Resolve the close-size against a position, applying the spec’s cap rules:
  • orderSize === 0 is the Hyperliquid convention for “close entire position” used by trigger orders → close the full position size.
  • Otherwise cap at the absolute position size; an order larger than the position can only close what’s open.
Inputs are non-negative magnitudes.
Returns: number

expectedRealizedPnlForOpenOrder

Expected rPnL for a resting limit order against a matching position. Reducing requires opposite sides (long position + SELL, short position + BUY). Same-side orders add to the position and return null. Returns null if there is no matching position or the inputs are non-finite.
Returns: number | null

expectedRealizedPnlForTriggerOrder

Expected rPnL for a TP/SL trigger order against a matching position. A trigger order is by construction a closing leg — its direction is the opposite of the position’s. With no matching position there is nothing to close, so rPnL is null. The trigger price (always present on the SDK TriggerOrder shape) is used as the rPnL price; the optional limitPrice for STOP_LIMIT / TAKE_PROFIT_LIMIT is the post-trigger limit, not the rPnL price.
Returns: number | null

TP/SL Calculations

calculateExpectedPnl

Calculate expected PnL if a trigger price is hit.
Returns: ExpectedPnl | null{ amount: number; percent: number } (signed; positive = profit). Returns null when triggerPrice, entryPrice, or margin is zero.

priceFromPercent

Convert a target PnL percentage to a trigger price.

percentFromPrice

Convert a trigger price to a PnL percentage.

Fee & Slippage

estimateFees

applySlippage

Adjust a price by a slippage percentage.

Quote Building

Pure helpers behind getQuote / subscribeQuote — walk a book to a VWAP fill and assemble a Quote. Most consumers call the client methods; reach for these to compute a quote from a book snapshot you already hold.

walkOrderbook

Walk one side of an orderbook to fill sizeUsd notional, accumulating base size and notional level-by-level to derive the VWAP fill. Levels are consumed in array order — pass asks for a buy and bids for a sell, each ordered best-price-first. Throws PerpsError (ValidationError) on a malformed level.
Returns: BookWalk{ baseSize, filledNotional, vwap, insufficientLiquidity }. insufficientLiquidity is true when the book cannot absorb the full notional (the walk returns the best obtainable fill).

buildQuote

Assemble a Quote from a resolved market, its live MarketContext, and its orderbook snapshot: walks the relevant side for the VWAP fill, derives price impact in basis points versus mark, and applies the base taker fee on the filled notional. Throws PerpsError (ValidationError) on a malformed book level.
Returns: Quote.

Account Summary

There is no standalone calculateAccountSummary util. Derive portfolio metrics with the PerpsClient.getAccountSummary() method:
Returns: AccountSummary{ portfolioValue, availableMargin, marginUsed, unrealizedPnl }, all string fields. The underlying pure function is summarizeAccount(account, positions, semantics), exported from @lifi/perps-sdk. The third argument, semantics: CollateralSemantics ('free' | 'net' | 'gross' | 'equity'), tells the roll-up how the collateral rows relate to the positions’ locked margin and unrealized PnL:

Order Classification

isTakeProfitOrder / isStopLossOrder / isTpSlOrder

Check whether an order is a TP, SL, or either.

classifyFill

classifyFill is deprecated — read Fill.classification (already populated on every fill) instead.
Classify a fill based on side and realized PnL. Returns a FillClassification enum value (Title-Case strings):

classifyFillFromPosition

Classify a fill into the full Open/Close/Increase/Reduce/Switch taxonomy using the signed position held before the fill. This is the accurate classifier classifyFill is deprecated in favour of.
Returns: FillClassification.

ACTIVE_ORDER_STATUSES / isActiveOrderStatus

ACTIVE_ORDER_STATUSES is the ReadonlySet<OrderStatus> of statuses for an order still resting on the book (OPEN, PENDING, PARTIALLY_FILLED, TRIGGERED); anything else is terminal and should be evicted from a cached orders list on a WS update. isActiveOrderStatus(status) is the membership check.

Validation

validateMargin

Check whether the user has sufficient margin for an order.

Parsing & Conversion

stringToFloat

Parse formatted currency/percentage strings to a number.

fromBaseUnits / fromBaseUnitsNumber

Convert a base-unit amount (passed as a string) to a decimal string or number.

Formatting

Display formatters for USD amounts, prices, and percentages. Each accepts a FormatInput (number, numeric string, or null/undefined) and an optional FormatOptions; non-finite input renders the placeholder (default '—').
FormatOptions is shared by every formatter:

formatNumber

Currency-symbol-free core formatter: two decimals with locale digit grouping by default. The other formatters build on it.

formatUsd

Unsigned USD, two decimals with digit grouping. Negatives place the - before the $.

formatSignedUsd

USD with an explicit sign, derived after rounding (so sub-cent magnitudes render $0.00).

formatSignedPercent

Percentage with an explicit sign and no grouping.

formatPrice

Unsigned price with decimals auto-detected from magnitude (override with options.decimals). Grouping applies once the absolute value reaches 1000.

formatCompactUsd

USD with a B/M/K suffix.

Explorer

explorerTxUrl / ExplorerChainId

Resolve a tx hash to a fully-qualified block-explorer URL for the settling chain. ExplorerChainId is the const map of supported settling chains (ETHEREUM 1, ARBITRUM_ONE 42161, LIGHTER 304, HYPERLIQUID 999) and the union of its values. explorerTxUrl returns undefined for an empty hash (no on-chain tx to link).
Returns: string | undefined. Use explorerTxUrlFromBase(baseUrl, txHash) for provider instances whose explorer is configured by URL rather than one of the known ExplorerChainId values; it returns undefined when either input is absent.

Deposit Assets and Gas

Deposit destinations are provider-owned and resolved through PerpsClient.getDepositFlow(). The SDK exports canonical on-chain asset identities for consumers that render or execute those flows:
Each asset is a DeclaredDepositAsset with { chainId, address, decimals }; identity is the chain/address pair, not the display symbol. getGasRecommendation(client, { chainId }) calls LI.FI’s gas suggestion API for the native-gas leg of a firstDepositPipeline. It returns GasRecommendationResponse, including available: false when LI.FI cannot source gas for that chain.

Exact Integer Scaling

Use scaleToInteger(value, decimals, policy) when a provider wire format requires an integer amount. It performs exact decimal arithmetic and requires an explicit off-grid policy: 'truncate' moves toward zero for sizes and collateral, while 'round' snaps prices half away from zero.
Invalid decimal strings, negative/non-integer precision, and values beyond Number.MAX_SAFE_INTEGER throw PerpsError with ValidationError.

Setup and Market Selection

  • selectUserSetupActions(provider.setup) returns only descriptors whose signers include USER. SDK-only setup steps are completed inline by checkSetup() and should not be rendered as user actions.
  • isActiveMarket(market) is false only when market.isDelisted === true.
  • toPerpsMarketDisplay(market) projects a perpetual market to the identity/capability shape embedded in positions, including isDelisted and positionMarginAdjustment.

Signing

signTypedData

Sign EIP-712 typed data with a private key. Useful for server-side signing without a wallet. Async — returns Promise<Hex>.

signTypedDataWithSigner

Sign EIP-712 typed data with an externally-provided viem WalletClient — a browser wallet (wagmi), private key, or mnemonic. Use this to sign the user arm of a setup step with the end-user’s wallet. Async — returns Promise<Hex>.

Hyperliquid-specific

These utilities are specific to Hyperliquid’s order formatting requirements and are exported from @lifi/perps-sdk-provider-hyperliquid (not the core SDK):
calculateLiquidationPrice and calculateMaintenanceMarginRate return number | undefined (undefined when inputs can’t yield a valid result).

calculateLiquidationPrice

calculateMaintenanceMarginRate

formatOrderPrice

Format a price for Hyperliquid submission (5 significant figures, correct decimal places).

formatOrderSize

Format a size for Hyperliquid submission (no trailing zeros).

getMaxPriceDecimals

Get the maximum number of price decimal places for an asset.