PaperEx.Portfolio (PaperEx v0.8.0)

Copy Markdown View Source

Top-level container for a paper trading account.

A Portfolio carries balance state, the set of currently-open positions, the history of closed positions, the execution-attempt ledger, and a free-form stats map. It is plain data — the engine that opens, closes, resolves positions and computes P&L lives in PaperEx.Engine, which threads an updated Portfolio through each apply_order/4 / resolve_market/4 call.

This module deliberately does not enforce a P&L invariant (current_balance == starting_balance + sum(closed.pnl) - capital_in_open). That arithmetic depends on the chosen P&L model (fixed payout vs mark-to-market), so it is the engine's and caller's concern, not the struct's. new/1 only validates field shapes.

Fields

  • :id — caller-assignable identifier.
  • :name — optional human-readable name. Useful when a consumer maintains multiple portfolios (e.g., "research" vs "live-mirror" per the two-modes design constraint).
  • :starting_balance (required) — initial currency balance. Non-negative number.
  • :current_balance — current free balance, defaulting to :starting_balance.
  • :peak_balance — high-water mark for drawdown computation, defaulting to :starting_balance.
  • :positions — list of currently-open PaperEx.Position structs. Defaults to []. Stored as a flat list; the engine scans it by {market_id, strategy} on each order.
  • :history — list of closed PaperEx.Position structs. Defaults to [].
  • :executions — execution-attempt ledger: list of PaperEx.Execution structs. Defaults to []. Held alongside :positions rather than embedded in them so misses and skips, which never produced a position, are still first-class.
  • :stats — free-form map for caller- or engine-computed summary stats (win rate, total P&L, max drawdown, etc.). Defaults to %{}.
  • :metadata — free-form map for caller-provided context (strategy family, mode, …).
  • :created_atDateTime.t(), defaults to DateTime.utc_now/0.

Summary

Functions

Builds a Portfolio from a map or keyword list.

Types

id()

@type id() :: term() | nil

t()

@type t() :: %PaperEx.Portfolio{
  created_at: DateTime.t(),
  current_balance: number(),
  executions: [PaperEx.Execution.t()],
  history: [PaperEx.Position.t()],
  id: id(),
  metadata: map(),
  name: String.t() | nil,
  peak_balance: number(),
  positions: [PaperEx.Position.t()],
  starting_balance: number(),
  stats: map()
}

Functions

new(attrs)

@spec new(keyword() | map()) :: t()

Builds a Portfolio from a map or keyword list.

Required: :starting_balance. Other fields default to sensible initial values. :current_balance and :peak_balance default to :starting_balance when not provided.