@somnia-chain/markets-sdk / index / computePositionPnL
Function: computePositionPnL()
computePositionPnL(
events,balances,market,oneCollateral,opts?):BinaryPositionPnL
Defined in: packages/sdk/src/derivedReads.ts:521
Fold a PnLEvent stream + current balances into a
BinaryPositionPnL, avg-cost basis, RAW units. oneCollateral = 10^quoteDecimals. Prices arrive in YES terms; a NO event is re-expressed to
NO terms (oneCollateral − yesPrice) here so the two books stay separate.
THE STREAM MUST BE IN CHAIN ORDER - block, then log index. This is an average-cost roll, so order changes the answer: a sale folded before the buy that opened the leg is clamped to nothing and its realization is lost. A PnLEvent carries no timestamp, and ordering by the unix second would not be enough anyway, since two events routinely share one. pnlEventsFor produces a stream that satisfies this.
An unresolved market that has never traded has no mark price. When
market.lastPrice is null and opts.bookTop supplies no quote,
markPrice, markValue and unrealizedPnl are null on both legs and on
the total. balance, costBasis, avgCost and realizedPnl stay exact,
because none of them depends on a mark.
Errors
Throws InvalidInputError when a void has a present but invalid payout vector. A legacy row with both vector fields absent keeps the documented half-payout fallback.
Parameters
events
PnLEvent[]
balances
balanceYes
bigint
balanceNo
bigint
market
Pick<BinaryMarket, "quoteDecimals" | "lastPrice" | "winningOutcome" | "voided" | "payoutNumerators" | "payoutDenominator">
oneCollateral
bigint
opts?
bookTop?
Top of the YES book — clamps the mark to live quotes (see markYesPrice).