Skip to main content
Mark price is the reference price used for PnL and liquidation checks. It is designed to resist manipulation by combining multiple inputs and applying staleness/divergence rules.

Design Goals

Phoenix was designed with the following core principles:
  • Aim to closely track spot price movements for fair PnL and valuations
  • Help protect against manipulation or distortions from temporary liquidity shocks on individual venues
  • Seek to reduce the risk of unnecessary liquidation wicks due to short-term anomalies or low-liquidity events such as volatile market conditions, oracle delays, or network issues that may cause deviations

Calculation

Mark price aggregates three components:

  • If all three components are valid, the mark price is the weighted median of the three.
  • If only two are valid, it falls back to a weighted average of those two.
  • If fewer than two are valid, the mark price is not updated.
  1. Book Price
    The median of best bid, best ask, and last trade on the Phoenix order book, after each is clamped to a baseline price within a configurable radius. This limits the impact of outlier quotes or prints. Valid only if best bid, best ask, and last trade are all non‑zero and the last trade is not stale. Staleness: book price uses the last trade slot; it is stale when last_update_slot + stale_threshold < current_slot. Default threshold is 100 slots (configurable per market).
  2. Adjusted Spot (Oracle) Price
    The median spot‑oracle price, adjusted by an EMA of the book‑mid minus spot spread. The EMA tracks the spread between the clamped book mid and the median spot price to smooths short‑lived order‑book spikes while keeping the mark anchored to spot. The book mid is clamped within ema_diff_radius of spot before computing the spread. The EMA updates each slot; if there’s no valid book mid, the EMA resets to zero. The adjusted spot price is spot_median + EMA(spread). Valid only if at least the minimum oracle quorum has non‑divergent, non‑stale spot prices and the resulting median spot price is non‑zero. Staleness: spot prices are stale when last_update_slot + stale_threshold < current_slot. Default threshold is 25 slots (configurable per market).
    Spot exchange weights:
    • Binance (weight 3)
    • OKX (weight 3)
  3. Perp Exchange Price
    The median of external perp prices from oracle feeds. (Exchange sources and their weights are set in the oracle configuration.) Valid only if at least the minimum oracle quorum has non‑divergent, non‑stale perp prices and the resulting median perp price is non‑zero. Staleness: perp exchange prices are stale when last_update_slot + stale_threshold < current_slot. Default threshold is 25 slots (configurable per market).
    Perpetual exchange weights:
    • Binance (weight 3)
    • Bybit (weight 2)
    • OKX (weight 2)
    • MEXC (weight 1)