Margin hooks
Derived helpers for how much margin a trade can spend.
Every hook on this page is a derived read — it composes other reads and a pure calculation; it does not hit a new endpoint of its own.
Import
import { useAccountMarginRisk, useAvailableInstantOpenMargin } from "@symmio/trading-react";useAccountMarginRisk
One account’s margin, equity and distance to liquidation. Composes useAccountBalanceInfo (with live: true by default) and feeds it to the pure core function calculateMarginRisk, so the figures refresh automatically when an open or close settles on-chain.
const { metrics } = useAccountMarginRisk({ account: virtualAccount, upnl });
if (metrics?.isLiquidatable) return <LiquidationWarning />;
return <Equity value={metrics?.equity} buffer={metrics?.liquidationBufferPercent} />;Pass the uPnL of this account’s whole book. equity = allocatedBalance + upnl, so the uPnL of a subset understates equity and everything derived from it. Fold it with aggregateGroupUpnl when the account’s positions are one group. Omitting it reports the account as if it were flat.
For a merged position, reach for useQuoteGroupMarginRisk instead — it resolves the group’s Virtual Account and folds the group’s uPnL for you. Use this hook directly for an account-level panel, or to fan out over a group that spans several accounts.
Every figure describes one liquidation domain. Each Virtual Account is liquidated on its own balance, so never sum these across accounts: the totals would add up, but the buffer would not, and a blend hides an account that is about to be liquidated behind a comfortable-looking average.
Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
account | Address? | undefined | Sub-account or Virtual Account. Idle until set. |
upnl | bigint? | 0n | Signed unrealized PnL of this whole account, wei. |
live | boolean? | true | Refetch the balance when an open/close settles on-chain. |
chainId | number? | config default | Optional chain override. |
config | Config? | provider value | Optional config override. |
Return type
interface UseAccountMarginRiskReturnType {
/** `undefined` until the balance read resolves. */
metrics?: MarginRiskMetrics;
/** The raw `balanceInfoOfPartyA` fields the metrics were computed from. */
balanceInfo?: AccountBalanceInfo;
isLoading: boolean;
error: SymmioRequestError | null;
}useAvailableInstantOpenMargin
The maximum initial margin an instant open can spend for an account on a market — the raw available balance shaved for the open fee (on the leveraged notional) and, for SHORT, a worst-case slippage fill. The close fee is not shaved — the contract charges it at close from the position (see Fees at close), not at open. Wire the result to the trade form’s Max chip and gate submit on it.
Under the hood it composes useAccountBalanceOf (with live: true) + useFeeForUser and feeds them to the pure core function calculateAvailableInstantOpenMargin. Because the balance read is live, the result refetches automatically when an open/close settles on-chain — the Max chip stays fresh with no extra wiring.
import { PositionType } from "@symmio/trading-core";
import { useAvailableInstantOpenMargin } from "@symmio/trading-react";
const { availableMargin, availableMarginWei } = useAvailableInstantOpenMargin({
account: subAccount,
symbolId: market.symbol_id,
leverage,
positionType: side === "short" ? PositionType.SHORT : PositionType.LONG,
slippage, // percent, e.g. 5
});
// Max chip
<button onClick={() => setMargin(availableMargin)}>Max {availableMargin}</button>;Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
account | Address? | undefined | SubAccount to spend margin from. Idle until set. |
symbolId | bigint | number? | undefined | Market symbol id, for the fee lookup. Idle until set. |
leverage | number | — | Requested leverage (integer ≥ 1). |
positionType | PositionType | — | LONG skips the slippage cap; SHORT applies it. |
slippage | number | — | Slippage percent, e.g. 5. |
chainId | number? | config default | Optional chain override. |
config | Config? | provider value | Optional config override. |
Return type
interface UseAvailableInstantOpenMarginReturnType {
/** Spendable margin in 18-decimal wei; `undefined` until balance + fees load. */
availableMarginWei: bigint | undefined;
/** `availableMarginWei` as a decimal string; `"0"` when unavailable. */
availableMargin: string;
/** `true` while the underlying balance / fee reads are loading. */
isLoading: boolean;
/** First error from the balance / fee reads, if any. */
error: SymmioRequestError | null;
/** Refetch the underlying balance + fee reads. */
refetch: () => Promise<void>;
}The shave formula: available = balance × max(0, 1 − slippageFactor) × max(0, 1 − leverage × openFee), where
slippageFactor = slippage on SHORT and 0 on LONG. Only the open fee is shaved — the close fee is charged at close
from the position. See
calculateAvailableInstantOpenMargin for the
framework-agnostic function and the reasoning behind each shave.
On a lowcap (Enigma) solver, prefer full-balance funding for the Max flow. The shaved figure above exists for a
typed initialMargin — it predicts how much of the balance a typed open can spend. A lowcap Max is better served by
passing fund: { mode: "full-balance", balance } to the open instead: it deploys the raw balance into the position’s
VA and sizes the quantity down to fit, so nothing is shaved or stranded. See
Full-balance funding.
Related
- Margin & risk (core) —
calculateMarginRisk, the pure fold behinduseAccountMarginRisk. useQuoteGroupMarginRisk— the same figures for a merged position.- AccountLayer hooks —
useAccountBalanceOf(the balance this shaves) and itsliveoption. - Fees hooks —
useFeeForUser, the fee rates this consumes. - InstantLayer / Solvers —
useInstantOpenAuto, which spends the margin.
Automatic sizing for typed lowcap margin
For typed lowcap market opens, prefer passing the raw available SubAccount balance as availableBalance to usePrepareInstantOpenParams, useInstantOpenFees, and the submission inputs. Core rejects a typed amount above the raw balance. For amounts within the balance, it keeps typed sizing when required funding fits and automatically uses full-balance sizing when costs push that funding above the balance. Do not block these orders using the fee-adjusted availableMarginWei cap. See automatic fallback and preview readiness. Other order types retain their existing margin checks.