Skip to content

Pre-trade risk concepts

This guide explains the economics and rules behind Risk Service pre-trade checks. It matches how risk-service computes values where noted; field names align with gRPC / risk.pretrade_decision.v1 / risk.exposure_snapshot.v1.

A reduce-only order may only decrease or close an existing position. It must not open a new position or add to the same side.

SituationReject reasonTypical message
No open position for that user and symbol (or empty size)REDUCE_ONLY_NO_POSITIONNo position to reduce
Order side would increase the position (e.g. BUY when long, SELL when short)REDUCE_ONLY_INVALID_SIDEe.g. Reduce-only BUY requires a short position / Reduce-only SELL requires a long position
Order quantity greater than absolute position sizeREDUCE_ONLY_EXCEEDS_SIZEOrder size exceeds position size
Position size or order quantity not a valid positive decimal (parse error)INTERNAL_ERRORe.g. Invalid position size / Invalid order quantity

Side rules (signed position size):

  • Long position (positive size): only SELL reduce-only is valid (reduces long).
  • Short position (negative size): only BUY reduce-only is valid (reduces short).

Long +0.5 BTC

OrderResult
SELL 0.1, reduce_only=trueApproved (reduces long)
SELL 0.5, reduce_only=trueApproved (closes long)
SELL 0.7, reduce_only=trueRejected — REDUCE_ONLY_EXCEEDS_SIZE
BUY 0.1, reduce_only=trueRejected — REDUCE_ONLY_INVALID_SIDE

Short −0.5 BTC

OrderResult
BUY 0.1, reduce_only=trueApproved (reduces short)
SELL 0.1, reduce_only=trueRejected — REDUCE_ONLY_INVALID_SIDE

No position

OrderResult
Any reduce-only orderRejected — REDUCE_ONLY_NO_POSITION

Portfolio unrealized PnL is the sum of unrealized PnL across all open positions for a user (all symbols). Each position has its own unrealized PnL; the portfolio figure is the total.

For each open position:

Unrealized PnL = (Mark price − Entry price) × Position size

(Size is signed: long positive, short negative, so the formula is correct for both sides.)

Portfolio unrealized PnL = Σ (per-position unrealized PnL).

SymbolSizeEntryMarkUnrealized PnL
BTCUSDT+0.560,00062,000(62,000 − 60,000) × 0.5 = +1,000
ETHUSDT−23,0002,800(2,800 − 3,000) × (−2) = +400
SOLUSDT1010095(95 − 100) × 10 = −50

Portfolio unrealized PnL = 1,000 + 400 − 50 = +1,350.

In cross-margin setups, one wallet backs all positions. Risk uses portfolio-level PnL, not a single symbol in isolation.

In risk-service, equity used for pre-trade is:

Equity = Available wallet balance (for margin) + Portfolio unrealized PnL

That equity drives:

  • Margin sufficiency checks
  • Projected leverage (see below)
  • Projected margin ratio vs maintenance (see below)
  • Liquidation-risk style signals in pre-trade

Initial margin is the minimum collateral needed to open or increase exposure: “Does the user have enough equity to support this trade?”

Required initial margin = Projected notional ÷ Max leverage

  • Projected notional — position value after the order (for the logic below; see next section for the full service definition).
  • Max leverage — effective cap for that user/symbol/instrument (minimum of instrument, user profile, tier, etc., as enforced by the engine).
  • Order adds 0.5 BTC exposure at mark 60,000 → projected notional 30,000
  • Max leverage 10×

Required initial margin = 30,000 ÷ 10 = 3,000 (user needs enough equity to cover this, per service rules).

gRPC exposes this as required_initial_margin; Kafka risk.exposure_snapshot.v1 includes required_initial_margin.


Meaning: Notional value of exposure after the order is applied, in the context of the pre-trade calculation.

Intuition (single symbol):

Projected notional ≈ |Position size after fill| × Mark price
(plus the effect of other exposure on the same symbol the engine includes.)

  • Exposure limits
  • Tier selection (maintenance % often depends on notional band)
  • Required initial margin (notional ÷ max leverage)
  • Published on events as projected_notional (decimal string)

For the symbol under check, risk-service aggregates marked position notional, new order notional, and open-order notional into one projected notional before leverage and margin math. So it is not always “only one position × mark”; open orders on the same symbol are included.


Purpose: Estimate how leveraged the account is after the order, relative to equity.

Projected leverage = Projected notional ÷ Equity

  • Projected notional — as computed for the check (symbol-scoped aggregate above).
  • Equity — wallet available for margin plus portfolio unrealized PnL (cross-margin style).
  • After the order, projected position 0.7 BTC at mark 60,000 → projected notional 42,000
  • Equity 3,000

Projected leverage = 42,000 ÷ 3,000 = 14×

Pre-trade compares this to max allowed leverage and may reject with MAX_LEVERAGE_EXCEEDED.

Exposed as projected_leverage in decisions and exposure snapshots.


Many venues use the words “margin ratio” in different ways. Two useful ideas:

Common alternative definition (exposure vs equity)

Section titled “Common alternative definition (exposure vs equity)”

Some documents define:

Margin ratio (alternative) = Total position value ÷ Equity

That is essentially “how many times notional is covered by equity” (related to leverage). This is not the same as the projected_margin_ratio string emitted by risk-service.

In risk-service, after applying a maintenance margin amount from the margin tier (maintenance % × projected notional):

Projected margin ratio = Equity ÷ Maintenance margin

  • Higher ratio → more cushion vs maintenance requirement.
  • Liquidation risk flags when this ratio falls below a configured threshold (e.g. equity no longer covers maintenance adequately).

So in APIs and Kafka, read projected_margin_ratio as equity divided by required maintenance margin for the projected state, not “notional divided by equity.”

If maintenance margin for the projected state is 1,500 and equity is 3,000:

Projected margin ratio = 3,000 ÷ 1,500 = 2 (equity is 2× maintenance).


ConceptTypical field(s)
Equity after cross PnLequity
Notional after order (aggregate)projected_notional
Leverage vs equityprojected_leverage
Equity vs maintenanceprojected_margin_ratio
Collateral to open/increaserequired_initial_margin
Near-liquidation style flagliquidation_risk (boolean)