QuoteGroupUpnl
Aggregated unrealized PnL for one grouped position, valued at a single mark price. Produced by aggregateGroupUpnl.
Every amount is 18-decimal wei bigint, matching UnifiedQuote.
Sign convention — plain trader convention: a positive upnl means the group is in profit. This is the same polarity as QuoteGroupFunding.netReceived, so the two folds can be read, coloured, and added together without either being negated.
Properties
upnlbigintrequiredΣ signed unrealized PnL across the group’s valued children (wei). Positive = in profit. A lower bound in
magnitude while isComplete is false — it is never suppressed to 0n.
openNotionalbigintrequiredΣ openQuantity × openedPrice across the valued children (wei) — the at-entry position value returnPercent
divides by. 0n when nothing was valued.
openMarginbigintrequiredΣ locked margin backing the still-open size of the valued children (wei) — the capital at risk upnlPercent divides
by. Each child contributes every leg of its frozen initialLockedValues (else lockedValues) prorated by
openQuantity / quantity. 0n when nothing was valued.
returnPercentbigint | undefinedUnleveraged return — upnl / openNotional × 100 as an 18-decimal fixed-point percent (12.5% → 12_500000000000000000n), signed with upnl. How far the market moved in the group’s favour. undefined — never
0n — when nothing was valued.
upnlPercentbigint | undefinedLeveraged return on capital — upnl / openMargin × 100, same fixed-point convention and sign. The group counterpart
of calculateQuoteUpnl’s upnlPercent, and the figure to show beside the uPnL amount. undefined when
openMargin is 0n.
valuedCountnumberrequiredNumber of children with open size that were valued against the mark price.
unvaluedCountnumberrequiredNumber of children with open size whose open price is not settled yet, so their PnL is unknown. Resting orders and fully-closed children are not counted here — they have no unrealized PnL to be missing.
isCompletebooleanrequiredtrue only when a mark price was given, at least one child was valued, and none was left unvalued. Check it before
presenting upnl — or anything derived from it, such as equity — as final.
Two percentages, two questions
returnPercent answers how far did the market move for this position; upnlPercent answers what did that do to the capital behind it. They differ by the group’s leverage, and the second is the one traders read:
/** A 10× position 10% in the money is up 100% on margin. */
upnl.returnPercent; // 10_000000000000000000n → +10%
upnl.upnlPercent; // 100_000000000000000000n → +100%Both are folds of the group’s totals — Σ upnl / Σ basis — never an average of the children’s individual percentages. Where the children share a leverage the two definitions agree; where they differ, a mean of ratios is a number no position actually earned. The fold’s denominator is also the one QuoteGroupMetrics.leverage uses, so upnlPercent ≈ returnPercent × leverage holds by construction.
Both are undefined rather than 0n when their basis is missing, because 0n is a real flat return. upnlPercent alone drops out when the valued children carry no locked collateral — there is no capital base to return on — while returnPercent still stands.
Why a consumer must check isComplete
upnl always renders a number, so an incomplete fold looks identical to a complete one — just smaller. isComplete: false means one of three things, and all of them are “PnL unknown”, never “no PnL”:
- No mark price yet. The feed has not ticked;
upnlis0nbecause nothing was valued. unvaluedCount > 0. Some position’s fill price has not settled, so its contribution is missing.- Nothing to value at all — every child is a resting order, closed, or the group is empty.
if (!upnl.isComplete) {
/** Show a skeleton. Do not render `0` as the position's PnL. */
return <Skeleton />;
}This matters most downstream: equity = totalMargin + upnl, so an incomplete uPnL silently produces an equity figure that is wrong by the missing amount. Gate equity and the liquidation buffer on this flag; the margin legs themselves are uPnL-independent and can render immediately.
The same caveat covers both percentages: they describe the valued subset only, so an incomplete fold reports the return of the children that could be priced, not of the group.
Related
aggregateGroupUpnl— the fold that produces this.calculateMarginRisk— takesupnlas its unrealized-PnL input.QuoteGroupMetrics— the price-independent aggregations over the same children.