Skip to main content

Oracle Price

The oracle price is the external spot reference for each asset, sourced from Pyth. Pyth pushes low-latency, real-time prices in a distributed manner directly to the BULK Network, providing a manipulation-resistant benchmark decoupled from BULK’s internal order book. Oracle price updates flow into the executor via PythOracle actions, where they pass through a price filter (volatility guard against stale or spurious updates) before being accepted.

Mark Price

The mark price is the reference price used for PnL, liquidation triggers, and conditional order activation. BULK computes it using a robust model, a composite of three components that adapts to market conditions.

Component 1: Premium-Adjusted Oracle Price

Poracle-adj=Poracle−EMA150s(Poracle−Pbook)P_{\text{oracle-adj}} = P_{\text{oracle}} - \text{EMA}_{150s}(P_{\text{oracle}} - P_{\text{book}}) Starts with the Pyth oracle price and subtracts a 150-second EMA of the premium between the oracle and the depth-weighted order book mid-price. This allows the mark price to track persistent premiums or discounts on BULK without being swayed by temporary noise.

Component 2: Depth-Weighted Book Price (Denoised)

Pbook=median(SizeWeightedMidt−2, SizeWeightedMidt−1, SizeWeightedMidt)P_{\text{book}} = \text{median}\left(\text{SizeWeightedMid}_{t-2},\ \text{SizeWeightedMid}_{t-1},\ \text{SizeWeightedMid}_{t}\right) A depth-weighted mid-price from BULK’s order book, passed through a rolling median filter to remove outlier ticks. The size-weighted mid accounts for the actual liquidity at each level rather than just the top-of-book.

Component 3: Smoothed Book Price

Psmooth=EMA30s(Pbook)P_{\text{smooth}} = \text{EMA}_{30s}(P_{\text{book}}) A 30-second EMA of the denoised book price. Acts as a stabilizing factor that dampens short-term fluctuations.

Final Calculation

In normal conditions, the three components are sorted and the median is selected: Pmark=median(Poracle-adj, Pbook, Psmooth)P_{\text{mark}} = \text{median}(P_{\text{oracle-adj}},\ P_{\text{book}},\ P_{\text{smooth}}) Volatility override: When instantaneous volatility (measured via Hawkes IRV or stdev, whichever is larger) exceeds a configurable threshold, the model bypasses the median smoothing and uses the raw depth-weighted book price directly. This ensures the mark price stays reactive during fast-moving markets.

Stale-Book Oracle Bias

If the order book has not been updated for an extended period, the mark price biases toward the oracle price on a sigmoid curve: Pfinal=(1−b)⋅Pcomputed+b⋅PoracleP_{\text{final}} = (1 - b) \cdot P_{\text{computed}} + b \cdot P_{\text{oracle}} Where the bias factor bb is 0 when book age is under 1 (fresh book), and when age reaches or exceeds 1: b=tanh⁡((age−0.5)⋅10)⋅0.5+0.5b = \tanh\left((\text{age} - 0.5) \cdot 10\right) \cdot 0.5 + 0.5 And age is the book staleness relative to the decay window (in minutes). As the book grows stale, bb rises from 0 toward 1 on a sigmoid curve, and the mark price converges smoothly to the oracle, ensuring fair pricing even in low-liquidity conditions.
Margin calculations use the mark price for notional values and PnL, but maintenance margin requirements are driven by lambda surfaces that depend on the volatility regime, not the mark price directly. See Margin for how regimes affect margin requirements.

Entry Price

The entry price represents the volume-weighted average price (VWAP) at which your current position was established. It is computed and stored by the clearing engine on every fill:
  • Position increase: VWAP is updated to blend the existing entry price with the new fill price, weighted by size
  • Position decrease: Entry price stays the same (only realized PnL is booked)
  • Position flip (e.g. long to short): Entry price resets to the fill price of the new direction
Entry price is stored as a scaled integer (u64) internally to avoid floating-point drift.

Unrealized PnL

Unrealized PnL is always computed against the mark price: PnLunrealized=Q×(Pmark−Pentry)\text{PnL}_{\text{unrealized}} = Q \times (P_{\text{mark}} - P_{\text{entry}}) Where QQ is the signed position size (positive for long, negative for short) and PentryP_{\text{entry}} is the VWAP entry price. This ensures PnL reflects fair value, not last traded price. Your mark equity is: Emark=C+∑iPnLunrealized,iE_{\text{mark}} = C + \sum_i \text{PnL}_{\text{unrealized},i} Where CC is your USDC collateral. For liquidation, BULK also computes closeout equity by applying the estimated adverse cost of closing every position through current depth and nearby cascade risk. Liquidation requires closeout equity below reserve-adjusted portfolio maintenance margin and negative mark-price position PnL. See Liquidations.