Simulating PM Risk
Every number described in Portfolio Margin can be read back for your account, and every trade can be previewed before you send it. The simulator is not a separate model: it runs the same margin code, on the same policy and the same engine snapshot, that checks your orders and runs the liquidation watcher.
In the app
The Portfolio margin page (/risk/span) shows, for a PM account:
- equity, IM, MM, buying power and maintenance buffer
- scanning risk, option floor and gamma overlay separately
- the scenario grid for each underlying, with the P&L of every scenario and every leg
- Simulate positions: add hypothetical legs to your book, or replace it, and compare current against simulated IM and MM. A simulation never places an order or changes account state.
The page refreshes every 5 seconds.
Endpoints
| Endpoint | What it answers | Auth |
|---|---|---|
GET /portfolio?wallet= | Current equity, IM, MM and positions | None |
GET /risk/grid?wallet= | Current scanning risk, floor, overlay, and the per-underlying scenario matrix | None |
POST /risk/simulate/portfolio | IM and MM if your positions were different | None |
POST /risk/simulate/orders | Whether an order or package would pass the margin check, and its IM cost | None |
GET /liquidation/status?wallet= | Liquidation state and shortfall | None |
All of them take your manager wallet as wallet; Hypercall resolves it to your PM account. GET /risk/grid answers only for PM accounts.
Risk grid
GET /risk/grid returns the account's current requirement and, per underlying, the scenarios that underlying is scored on (its own grid, including any extra scenarios) with:
scenarios[]:id,spot_shock_pct,vol_shock_pct,pnl_weight,is_tailand the underlying'stotal_pnlin that scenarioextended_risk_matrix.instruments[]: per-legscenario_pnls, aligned withscenarios
scanning_risk at the top level is the charged number: each underlying's worst weighted loss, summed. The matrix's worst_scenario_index is a diagnostic for one underlying's grid and does not drive margin across underlyings.
Portfolio simulation
curl -X POST https://api.hypercall.xyz/risk/simulate/portfolio \
-H 'Content-Type: application/json' \
-d '{
"wallet": "0xYourManagerWallet",
"add_positions": true,
"positions": [
{"symbol": "BTC-20261231-100000-C", "quantity": "-1"},
{"symbol": "BTC-20261231-110000-C", "quantity": "1"},
{"symbol": "BTC-PERP", "quantity": "0.25"}
]
}'
add_positions: true(the default) adds each signed quantity to your current position.falsereplaces your book with exactly the list.- Up to 50 symbols, each listed once. Option and perp symbols are both accepted.
- Positions are valued at current marks. No premium is charged and no order book is consulted.
The response has current, simulated and delta. In each summary, read:
| Field | Meaning |
|---|---|
equity | Equity as defined on the methodology page |
position_initial_margin | IM on positions: max(scanning risk, floor) + overlay |
position_maintenance_margin | MM, 0.85 × position IM |
open_orders_initial_margin | Reservation for your live resting orders |
total_initial_margin | Position IM plus open-order IM |
initial_margin_available | Equity minus total IM. Negative means new risk is refused |
maintenance_margin_available | Equity minus MM. Negative means liquidation |
scanning_risk, option_floor, gamma_overlay | The three components |
underlyings[] | The per-underlying scenario matrix, as in GET /risk/grid |
venue_liquidation | Present when you hold Hyperliquid perps: whether each Hyperliquid compartment survives the grid (hedge_survives), the collateral that would be lost, and the venue-aware IM and MM |
metadata identifies the engine snapshot the simulation ran on (l2_seq, evaluated_at_ms).
Live pending inventory
Both simulation responses include live_pending, captured from the same snapshot as current, before any requested changes:
orderscontains outright option and perp orders, including those with a zero current margin charge. Each entry hasorder_id,symbol,side,price,remaining_size,is_perp, andreduce_only.combo_orderskeeps each atomic parent together, with its canonical combosymbol,order_id,side, signed netprice,remaining_size,reduce_only, andlegs. Each leg has aninstrument_id,symbol, and signed integerratio, relative to buying the parent. Selling reverses those ratios. A parent price may be zero or negative.perp_directivescontains managed perp reservations withdirective_id,symbol,side,price,remaining_size, andfill_evidence_timestamp_ms. A non-null fill-evidence timestamp means the reservation holds observed fills awaiting position reconciliation; it is not an independently executable unfilled order.
Units are explicit: prices and quantities are decimal strings. Quantities are human contract, combo, or base-asset units, never raw micro units. Order IDs, instrument IDs, and ratios are exact strings. side is "Buy" or "Sell".
All three arrays are required, including when empty. Missing inventory on an older server is unavailable evidence, not an empty portfolio. Entries are not truncated and are ordered by their exact numeric order ID or directive UUID. The inventory covers the node's order and managed reservation stores. It does not enumerate outstanding RFQ quotes or orders placed directly on an external venue outside the managed flow; track those commitments separately.
Do not add these entries again as hypothetical_open_orders: they already belong to the current snapshot and are included by the applicable margin model. Hypothetical orders are additional orders you have not placed. Snapshot revisions identify the observation; they do not guarantee the inventory remains unchanged after the response.
Order simulation
POST /risk/simulate/orders runs the financial part of order admission without placing anything:
execution_mode: "resting"takes exactly one order and charges it as a resting order.execution_mode: "atomic"evaluates the legs as a package that fills together, the way a combo is margined.hypothetical_open_orderslets you add resting orders you have not placed yet, evaluated beforeorders.
The response adds admissible and, when false, a rejection_reason. The delta block shows the IM the order would consume. Request examples are in Authentication.
The order simulator answers the margin question only. Matching, price bands, RPI, nonces, rate limits and trading halts are not simulated, and engine state can move before you send the real order.
Errors
| Status | error | What it means |
|---|---|---|
400 | invalid_simulation | Malformed request, unknown or expired symbol, duplicate symbol, or more than 50 items |
429 | risk_simulation_saturated | Simulation capacity is shared and limited; retry with backoff |
503 | risk_inputs_unavailable | An input is missing or stale, for example no IV mark for an option, or a stale HyperCore snapshot. The real order would be refused for the same reason |
Rate limits for simulations are listed in Rate Limits.