Current section
Files
Jump to
Current section
Files
lib/ccxt/order_book.ex
defmodule CCXT.OrderBook do
@moduledoc """
Unified order book (market depth) data.
Contains sorted bid and ask price levels, each as `[price, amount]` pairs.
Bids are sorted highest-first, asks lowest-first.
## Fields
* `symbol` - Unified symbol (e.g., "BTC/USDT")
* `timestamp` - Exchange timestamp in milliseconds
* `datetime` - ISO 8601 datetime string
* `nonce` - Incremental update sequence number
* `bids` - List of bid levels as `[price, amount]` pairs, highest first
* `asks` - List of ask levels as `[price, amount]` pairs, lowest first
* `info` - Raw exchange response
"""
import JSONSpec, only: [schema: 2]
@type t :: %__MODULE__{
symbol: String.t() | nil,
timestamp: integer() | nil,
datetime: String.t() | nil,
nonce: integer() | nil,
bids: [[number()]],
asks: [[number()]],
info: map() | nil
}
defstruct [
:symbol,
:timestamp,
:datetime,
:nonce,
:info,
bids: [],
asks: []
]
@doc "Returns the best (highest) bid price, or nil if empty/malformed."
@spec best_bid(t()) :: number() | nil
def best_bid(%__MODULE__{bids: [[price | _] | _]}) when is_number(price), do: price
def best_bid(%__MODULE__{}), do: nil
@doc "Returns the best (lowest) ask price, or nil if empty/malformed."
@spec best_ask(t()) :: number() | nil
def best_ask(%__MODULE__{asks: [[price | _] | _]}) when is_number(price), do: price
def best_ask(%__MODULE__{}), do: nil
@doc "Returns the spread (best ask price - best bid price), or nil if either side is empty/malformed."
@spec spread(t()) :: number() | nil
def spread(%__MODULE__{} = ob) do
with bid when is_number(bid) <- best_bid(ob),
ask when is_number(ask) <- best_ask(ob) do
ask - bid
else
_ -> nil
end
end
@json_schema schema(
%{
symbol: String.t() | nil,
timestamp: integer() | nil,
datetime: String.t() | nil,
nonce: integer() | nil,
bids: [[number()]],
asks: [[number()]],
info: map() | nil
},
doc: [
symbol: "Unified symbol (e.g., BTC/USDT)",
timestamp: "Exchange timestamp in milliseconds",
datetime: "ISO 8601 datetime string",
nonce: "Incremental update sequence number",
bids: "List of bid levels as [price, amount] pairs, highest first",
asks: "List of ask levels as [price, amount] pairs, lowest first",
info: "Raw exchange response"
]
)
@doc "JSON Schema for the OrderBook unified type."
@spec schema() :: map()
def schema, do: @json_schema
end