DpExchange.Core.Types.AuctionImbalance (DpExchangeCore v0.1.45)

Copy Markdown View Source

The order imbalance an exchange publishes ahead of an opening or closing auction.

Why this is its own type and not a quote

During an auction the continuous book stops being the price. What matters instead is how much can be matched, how much cannot, and at what price the auction would clear if it ran now — three numbers a Quote has nowhere to put and a TopOfBook describes a different market for.

A caller reading a continuous-market quote at 15:59 and acting on it is reading a book that is not where the close will happen.

:side is the venue's own value, unmapped

Venues publish the imbalance direction as a code, and the code tables differ. Webull's NOII documents imbalance_side with the example "2" and does not say what 2 means.

So this carries the venue's value as it was sent rather than an :buy/:sell atom guessed from a table nobody published. Getting that backwards would tell a caller there is unmatched buying pressure when there is selling — a wrong answer that looks entirely normal, and one that moves money in the wrong direction at the one moment of the day with the most volume behind it.

A package that establishes a venue's table can map it and say where the table came from. Until then the raw value is the honest answer.

The three prices are three different questions

  • :reference_price — what the auction is being measured against
  • :near_price — where it would clear on the orders in hand
  • :far_price — where it would clear in the extreme case

They are not interchangeable and none of them is "the price". A venue publishing only some of them leaves the rest nil.

Summary

Types

Which auction the imbalance belongs to.

t()

Functions

Whether the imbalance is large relative to what can be paired, as a ratio.

Builds a t/0, failing closed if a required field is absent or nil.

Types

auction()

@type auction() :: :opening | :closing

Which auction the imbalance belongs to.

t()

@type t() :: %DpExchange.Core.Types.AuctionImbalance{
  auction: auction(),
  far_price: Decimal.t() | nil,
  imbalance_quantity: Decimal.t() | nil,
  near_price: Decimal.t() | nil,
  observed_at: DateTime.t(),
  paired_quantity: Decimal.t() | nil,
  provider: atom() | String.t(),
  reference_price: Decimal.t() | nil,
  side: String.t() | nil,
  symbol: String.t(),
  venue_time: DateTime.t() | nil
}

Functions

imbalance_ratio(auction_imbalance)

@spec imbalance_ratio(t()) :: Decimal.t() | nil

Whether the imbalance is large relative to what can be paired, as a ratio.

nil when either quantity is absent — not zero. An unknown imbalance is not a small one, and a caller treating a missing number as "balanced" is making the same mistake as reading a missing liquidation price as safety.

Returns a Decimal so the caller decides what counts as large; this type has no opinion about a threshold and should not acquire one.

new(attrs)

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

Builds a t/0, failing closed if a required field is absent or nil.

@enforce_keys guards presence, not nil — see DpExchange.Core.Types.Validate.