PaperEx.Valuation (PaperEx v0.8.0)

Copy Markdown View Source

Pure mark-to-market valuation of open positions against caller- supplied snapshots.

The engine never fetches prices; this module turns a set of PaperEx.MarketSnapshots the caller already has (e.g. from a snapshot cache) into a net liquidation value for open positions. Nothing here mutates state or performs IO.

Pricing policy

  • :conservative (default) — value each position at the price you could actually close it at right now: longs at the best bid (what a sale would fetch), shorts at the best ask (what a buyback would cost). Missing book side → the position is unpriced.
  • :midpoint — value both sides at the snapshot midpoint. Requires both book sides; either side empty → unpriced.

Net liquidation value

Longs add shares * price; shorts subtract shares * price (the cost to cover). The total is what closing every open position at current prices would do to cash.

All-or-nothing totals

open_position_value/3 returns {:error, {:unpriced, ids}} when any open position lacks a usable snapshot/price — a partial total silently missing positions reads as "covered everything" when it didn't. Callers wanting partial data use the :by_position breakdown on the success shape, or filter positions first.

Summary

Types

Per-position valuation detail.

Functions

Net liquidation value of the open positions in portfolio_or_positions against snapshots (a map of market_id => MarketSnapshot).

Types

position_value()

@type position_value() :: %{
  position_id: term(),
  market_id: term(),
  side: :buy | :sell,
  shares: number(),
  price: number(),
  value: number()
}

Per-position valuation detail.

pricing()

@type pricing() :: :conservative | :midpoint

snapshots()

@type snapshots() :: %{required(term()) => PaperEx.MarketSnapshot.t()}

Functions

open_position_value(portfolio_or_positions, snapshots, opts \\ [])

@spec open_position_value(
  PaperEx.Portfolio.t() | [PaperEx.Position.t()],
  snapshots(),
  keyword()
) ::
  {:ok, %{value: number(), by_position: [position_value()]}}
  | {:error, {:unpriced, [term()]}}

Net liquidation value of the open positions in portfolio_or_positions against snapshots (a map of market_id => MarketSnapshot).

Returns {:ok, %{value: total, by_position: [...]}} when every open position priced, or {:error, {:unpriced, market_ids}} listing the markets that could not be priced (missing snapshot or empty required book side).

Options:

  • :pricing:conservative (default) or :midpoint.