Normalised order fill — a partial or complete execution of the caller's own order.
One fill is a single match against the book; a single order may produce many fills, so a caller reconstructing an order's economics sums its fills rather than reading any one of them.
Distinct from DpExchange.Core.Types.Trade, which is the public tape.
:timestamp is the venue's own, used as-is.
Summary
Types
@type liquidity() :: :maker | :taker | nil
@type t() :: %DpExchange.Core.Types.Fill{ fee: Decimal.t() | nil, fee_currency: String.t() | nil, liquidity: liquidity(), order_id: String.t(), price: Decimal.t(), provider: atom() | String.t(), quantity: Decimal.t(), side: :buy | :sell, symbol: String.t(), timestamp: DateTime.t(), trade_id: String.t() | nil }
Functions
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.
Also raises on a :side that is not :buy or :sell, and on a :liquidity that is not
:maker, :taker or nil: side: :long on a fill reads as no side to a consumer
matching the two the type states, and a "maker" string matches neither.
A :price of zero or less raises, as a public trade's does (Types.Trade): a match
happened at a price above zero, and a 0 is a decode bug (an absent price read as a number)
that would zero the order's average price in whoever sums the fills. A negative :fee stays
legal, since a maker rebate is a fee the venue paid.