@somnia-chain/markets-sdk


@somnia-chain/markets-sdk / index / PortfolioAnalytics

Interface: PortfolioAnalytics

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:179

The computed metrics plane — mirrors what a portfolio page renders.

Properties

timeframe

timeframe: PortfolioTimeframe

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:180


asOf

asOf: number

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:182

Upper bound of the series (ms).


equity

equity: EquityPoint[]

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:184

Cumulative window PnL over time, oldest first; first point is 0.


holdings

holdings: HoldingsPoint[]

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:215

Marked value of the traded book over time, oldest first, on the same sample grid as PortfolioAnalytics.equity. The first point is the carried-in book valued at the window start, not zero.

This series is a LEVEL, where equity is a change. It sums qty × mark over every open position at each sample, before the cost basis is taken off.

It sums SIGNED position value. Every book this fold keeps today is long-only, because applyTrade floors each market's quantity at zero, so today the sum cannot go below zero. Do not lock a chart axis to that. The module note above commits this fold to taking the perp plane as new event kinds, a perp book is signed, and a short marks negative.

The marks are the caller's, and this fold does not validate them. A negative price carries into this value unchanged, exactly as it already carries into the PnL and MWRR figures.

A position the sample cannot price is left OUT of the value rather than guessed at, and HoldingsPoint.unpricedMarkets counts what was left out. Check it before presenting a sample as the whole book.

It measures the TRADED BOOK, not the wallet. A token that arrived without a fill — bridged in, transferred in, minted — is not in the book, so it is not in this value. Idle quote balance is not a position, so it is not included either. PortfolioFundingEvents refine the capital base only, so a deposit inside the window does not step this curve. Read balances from the chain when you need what the wallet itself is worth.


pnl

pnl: object

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:216

totalUsd

totalUsd: number

Signed total PnL over the timeframe, USD (== last equity point).

buckets

buckets: PnlBucket[]


mwrr

mwrr: object

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:221

return

return: number | null

Period money-weighted return as a fraction: gainUsd over weightedCapitalUsd. Not annualized.

Null when the capital base is not meaningfully positive — at or below one US cent, which includes a base driven negative by withdrawals or by an account extracting more than it put in. Null is not zero: the other fields stay readable so a caller can present the window another way.

On the funding basis this can exceed 100% in either direction, because capital at risk for only part of the window is weighted down while the gain covers all of it. That is what a money-weighted period rate states, so it is reported rather than withheld. Read weightedCapitalUsd to see how much capital the figure measures against before presenting it as a headline.

gainUsd

gainUsd: number

Signed money gained over the period, USD.

depositedUsd

depositedUsd: number

Unweighted capital base: carried-in position value + the window's net flows, per capitalBasis. On the trades basis, buys deploy capital and the MATCHED proceeds of sells return it — proceeds of tokens never bought on the venue are scored nowhere, so an external seller reads 0 rather than a negative base. Signed.

weightedCapitalUsd

weightedCapitalUsd: number

The denominator the return divides by. On the funding basis this is the Modified Dietz base: carried-in value plus each external movement weighted by the fraction of the window remaining after it. On the trades basis it equals depositedUsd, because a trade moves capital already inside the account and weighting it would collapse the base for an account that merely rearranged what it held. Signed.

capitalBasis

capitalBasis: "trades" | "funding"

Which definition produced the capital figures. "funding" when the caller supplied PortfolioFundingEvents that fall inside the window, else "trades" — the proxy, which cannot see capital that never passed through a trade. Funding that predates the window does not select the funding basis: it contributes no in-window flow, and any capital it left invested is already in the carried-in position's value, which both bases count. Branch on this rather than on the package version.


volume

volume: object

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:269

periodUsd

periodUsd: number

Trading volume over the timeframe, USD.

lifetimeUsd

lifetimeUsd: number

Volume across every supplied event, USD.

sessionUsd?

optional sessionUsd?: number

Volume since sessionSince, when supplied.


feesSaved

feesSaved: object

Defined in: packages/sdk/src/unified/portfolioAnalytics.ts:277

cexRateBps

cexRateBps: number

The comparison taker rate (bps) the savings are computed against.

periodUsd

periodUsd: number

Volume × rate over the timeframe, USD.

lifetimeUsd

lifetimeUsd: number

Volume × rate across every supplied event, USD.