Exchange v0.1.0 Exchange.OrderBook View Source

Order Book Struct

The Order Book is the Exchange main data structure. It holds the Order Book in Memory where the MatchingEngine realizes the matches and register the Trades.

Example of and Order Book for Physical Gold (AUX) in London Market Orders with currency in Great British Pounds:

    %Exchange.OrderBook{
      name: :AUXLND,
      currency: :GBP,
      buy: %{},
      sell: %{},
      order_ids: MapSet.new(),
      ask_min: 99_999,
      bid_max: 0,
      max_price: 99_999,
      min_price: 0
    }

Buy and Sell Sides, price points and Orders

The OrderBook has a buy and sell keys that represent each of the sides.

Each side is a map indexed by an integer representing the price_point That contains a Queue of orders ordered by First In First Out (FIFO)

The queues of Exchange.Order are implemented using Qex (an Elixir wrapper for the erlang OTP :queue.

Example:

buy: %{
  4001 => #Qex<[
    %Exchange.Order{
      acknowledged_at: ~U[2020-03-31 14:02:20.534364Z],
      modified_at: ~U[2020-03-31 14:02:20.534374Z],
      order_id: "e3fbecca-736d-11ea-b415-8c8590538575",
      price: 3970,
      side: :buy,
      size: 750,
      trader_id: "10995c7c-736e-11ea-a987-8c8590538575",
      type: :limit
    }
  ]>,
  4000 => #Qex<[ Exchange.Order(1), ... Exchange.Order(n) ]>,
  3980 => #Qex<[ Exchange.Order(1), ... Exchange.Order(n) ]>

Other Attributes

  • name: Is the name of the ticker and the Id of the exchange. The exchange supports multiple matching engines identified by the different unique tickers.
  • currency: The currency that is supported inside this OrderBook. All orders must have prices in cents in that currency.
  • order_ids: Is an index of ids of the orders to see if and order is waiting for a match or not.

These are all attributes that represent prices in cents for currency:

  • ask_min: is the current minimum ask price on the sell side.
  • bid_max: is the current maximum bid price on the buy side.
  • max_price: is the maximum price in cents that we accept a buy order
  • min_price: is the minimum price in cents that we accept a sell order

Link to this section Summary

Functions

Updates the Order Book decrementing the bid_max by 1

Removes an %Order{} from the Order Book

Try to feth a matching buy/sell at the current bid_max/ask_min price

returns the highest asking volume

Updates the Order Book incrementing the ask_min by 1

Updates the Order Book incrementing the ask_min by 1 or decrementing the bid_max by 1 taking into account the order's side and price

Returns the list of open orders

Returns the list of open orders from a trader

This is the core of the Matching Engine. Our Matching Engine implements the Price-Time Matching Algorithm.

Queues an %Order{} in to the correct price_point in the order_book

Register Trade on Order Book completed_trades

Updates the Order Book setting ask_min

Updates the Order Book setting bid_max

returns spread for this exchange

Link to this section Types

Specs

order_book() :: %Exchange.OrderBook{
  ask_min: price_in_cents(),
  bid_max: price_in_cents(),
  buy: %{optional(price_in_cents()) => queue_of_orders()},
  completed_trades: list(),
  currency: atom(),
  expiration_list: term(),
  expired_orders: term(),
  max_price: price_in_cents(),
  min_price: price_in_cents(),
  name: atom(),
  order_ids: %{optional(String.t()) => {atom(), price_in_cents()}},
  sell: %{optional(price_in_cents()) => queue_of_orders()}
}

Specs

price_in_cents() :: integer()

Specs

queue_of_orders() :: %Qex{data: [Exchange.Order.order()]}

Specs

size_in_grams() :: integer()

Specs

ticker() :: atom()

Link to this section Functions

Link to this function

add_order_to_expirations(order_book, order)

View Source

Specs

add_order_to_expirations(order_book(), Exchange.Order.order()) :: order_book()
Link to this function

add_order_to_index(order_book, order)

View Source

Specs

add_order_to_index(order_book(), Exchange.Order.order()) :: order_book()
Link to this function

calculate_min_max_prices(order_book, order)

View Source

Specs

calculate_min_max_prices(order_book(), Exchange.Order.order()) :: order_book()
Link to this function

check_expired_orders!(order_book)

View Source

Specs

check_expired_orders!(order_book()) :: order_book()
Link to this function

completed_trades(order_book)

View Source

Specs

completed_trades(order_book()) :: list()
Link to this function

decrement_bid_max(order_book, price)

View Source

Specs

decrement_bid_max(order_book(), number()) :: order_book()

Updates the Order Book decrementing the bid_max by 1

Link to this function

dequeue_order(order_book, order)

View Source

Specs

dequeue_order(order_book(), Exchange.Order.order()) :: order_book()

Removes an %Order{} from the Order Book

Link to this function

dequeue_order_by_id(order_book, order_id)

View Source

Specs

dequeue_order_by_id(order_book(), String.t()) :: order_book()
Link to this function

fetch_matching_order(order_book, order)

View Source

Specs

fetch_matching_order(order_book(), Exchange.Order.order()) ::
  atom() | {atom(), Exchange.Order.order()}

Try to feth a matching buy/sell at the current bid_max/ask_min price

Link to this function

fetch_order_by_id(order_book, order_id)

View Source

Specs

fetch_order_by_id(order_book(), String.t()) :: Exchange.Order.order()
Link to this function

flush_expired_orders!(order_book)

View Source

Specs

flush_expired_orders!(order_book()) :: order_book()
Link to this function

flush_trades!(order_book)

View Source

Specs

flush_trades!(order_book()) :: order_book()
Link to this function

highest_ask_volume(order_book)

View Source

Specs

highest_ask_volume(order_book()) :: number()

returns the highest asking volume

Link to this function

highest_bid_volume(order_book)

View Source

Specs

highest_bid_volume(order_book()) :: number()
Link to this function

increment_ask_min(order_book, price)

View Source

Specs

increment_ask_min(order_book(), number()) :: order_book()

Updates the Order Book incrementing the ask_min by 1

Link to this function

increment_or_decrement(order_book, order)

View Source

Specs

increment_or_decrement(order_book(), Exchange.Order.order()) :: order_book()

Updates the Order Book incrementing the ask_min by 1 or decrementing the bid_max by 1 taking into account the order's side and price

Link to this function

insert_order_in_queue(order_book, order)

View Source

Specs

insert_order_in_queue(order_book(), Exchange.Order.order()) :: order_book()

Specs

open_orders(Exchange.OrderBook) :: [Exchange.Order]

Returns the list of open orders

Link to this function

open_orders_by_trader(order_book, trader_id)

View Source

Specs

open_orders_by_trader(Exchange.OrderBook, String) :: [Exchange.Order]

Returns the list of open orders from a trader

Link to this function

order_exists?(order_book, order_id)

View Source

Specs

order_exists?(order_book(), String.t()) :: boolean()

Specs

orders_to_list(map()) :: list()
Link to this function

pop_order_from_expiration(order_book)

View Source

Specs

pop_order_from_expiration(order_book()) :: order_book()
Link to this function

price_time_match(order_book, order)

View Source

Specs

price_time_match(order_book(), Exchange.Order.order()) :: order_book()

This is the core of the Matching Engine. Our Matching Engine implements the Price-Time Matching Algorithm.

The first Orders arriving at that price point have priority

Link to this function

queue_order(order_book, order)

View Source

Specs

queue_order(order_book(), Exchange.Order.order()) :: order_book()

Queues an %Order{} in to the correct price_point in the order_book

Link to this function

register_trade(order_book, order, matched_order)

View Source

Specs

Register Trade on Order Book completed_trades

Link to this function

remove_order_from_index(order_book, order)

View Source

Specs

remove_order_from_index(order_book(), Exchange.Order.order()) :: order_book()
Link to this function

set_ask_min(order_book, order)

View Source

Specs

set_ask_min(order_book(), Exchange.Order.order()) :: order_book()

Updates the Order Book setting ask_min

Link to this function

set_bid_max(order_book, order)

View Source

Specs

set_bid_max(order_book(), Exchange.Order.order()) :: order_book()

Updates the Order Book setting bid_max

Specs

spread(order_book()) :: number()

returns spread for this exchange

Link to this function

total_ask_orders(order_book)

View Source

Specs

total_ask_orders(order_book()) :: number()
Link to this function

total_bid_orders(order_book)

View Source

Specs

total_bid_orders(order_book()) :: number()
Link to this function

update_expired_orders(order_book, order_id)

View Source
Link to this function

update_order(order_book, order)

View Source

Specs

update_order(order_book(), Exchange.Order.order()) :: order_book()
Link to this function

update_queue(order_book, side, price_point, new_queue)

View Source

Specs

update_queue(order_book(), atom(), price_in_cents(), queue_of_orders()) ::
  order_book()