Exchange v0.2.5 Exchange.OrderBook View Source

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

Adds the expiring order to the Order Book's expiration_list, which is sorted by the exp_time afterwards.

Adds the order to the Order Book's order_ids. The order_ids is used to have a better performance when searching for specific order.

When an order is matched and removed from the order book the ask_min or bid_max must be updated. To update these values it is necessary to traverse the keys of the corresponding side of the Order Book, sort them and take the first element. When one of the sides is empty the value is set to max_price - 1 or min_price + 1 to the ask_min or bid_max, respectively.

Periodic function that is triggered every second. This function is used to verify if there are expired orders. The expired orders are added to the expired_orders, removed from the expiration_list and removed from the sell or buy side.

Returns the list of completed trades.

Removes an Exchange.Order from the Order Book

Removes an Exchange.Order using its order_id from the Order Book

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

Try to fetch a matching buy/sell with an order_id

Flushes all the expired orders from the OrderBook's expired_orders

Removes all the completed trades from the OrderBook.

Returns the sum of the size of all buy orders

Returns the sum of the size of all sell orders

Inserts an Exchange.Order in to the queue. The order is pushed to the end of the queue.

Returns the lastest price from a side of the order book

Returns the lastest size from a side of the order book

Returns the list of open orders

Returns the list of open orders from a trader by filtering the orders don't have trader_id

Verifies if an Exchange.Order with order_id exists in the Order Book

Returns the list resulting of flattening a Exchange.OrderBook.queue_of_orders()

Removes the first element from the OrderBook's experiration_list

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.

Queues an Exchange.Order in to the correct price_point in the Order Book

Generates a trade and adds it to the completed_trades of the order_book.

Removes the order to the Order Book's order_ids.

Updates the Order Book setting ask_min

Updates the Order Book setting bid_max

Returns spread for this exchange by calculating the difference between ask_min and bid_max

This function checks if there are any stop loss orders to activate. If yes then they are converted in market orders, removed and placed on the exchange. ## Parameters

Returns the number of active sell orders.

Returns the number of active buy orders.

Fetches the order with order_id and adds it to the Order Book's expired_orders

Updates an Exchange.Order in the Order Book

Updates an Exchange.OrderBook.queue_of_orders() from the Order Book

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 :: order_book(), Exchange.Order.order()) ::
  order_book()

Adds the expiring order to the Order Book's expiration_list, which is sorted by the exp_time afterwards.

Parameters

  • order_book: OrderBook that contains the expiration_list
Link to this function

add_order_to_index(order_book, order)

View Source

Specs

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

Adds the order to the Order Book's order_ids. The order_ids is used to have a better performance when searching for specific order.

Parameters

  • order_book: OrderBook that contains the order_ids
Link to this function

calculate_min_max_prices(order_book, order)

View Source

Specs

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

When an order is matched and removed from the order book the ask_min or bid_max must be updated. To update these values it is necessary to traverse the keys of the corresponding side of the Order Book, sort them and take the first element. When one of the sides is empty the value is set to max_price - 1 or min_price + 1 to the ask_min or bid_max, respectively.

Link to this function

check_expired_orders!(order_book)

View Source

Specs

check_expired_orders!(order_book :: order_book()) :: order_book()

Periodic function that is triggered every second. This function is used to verify if there are expired orders. The expired orders are added to the expired_orders, removed from the expiration_list and removed from the sell or buy side.

Parameters

  • order_book: OrderBook that contains the expired orders
Link to this function

completed_trades(order_book)

View Source

Specs

completed_trades(order_book :: order_book()) :: [Exchange.Trade]

Returns the list of completed trades.

Parameters

  • order_book: OrderBook that stores the completed trades
Link to this function

dequeue_order(order_book, order)

View Source

Specs

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

Removes an Exchange.Order from the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order to be removed
Link to this function

dequeue_order_by_id(order_book, order_id)

View Source

Specs

dequeue_order_by_id(order_book :: order_book(), order_id :: String.t()) ::
  order_book()

Removes an Exchange.Order using its order_id from the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order to be removed
Link to this function

fetch_matching_order(order_book, order)

View Source

Specs

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

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

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order used to search a matching order
Link to this function

fetch_order_by_id(order_book, order_id)

View Source

Specs

fetch_order_by_id(order_book :: order_book(), order_id :: String.t()) ::
  Exchange.Order.order()

Try to fetch a matching buy/sell with an order_id

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order used to search an order
Link to this function

flush_expired_orders!(order_book)

View Source

Specs

flush_expired_orders!(order_book :: order_book()) :: order_book()

Flushes all the expired orders from the OrderBook's expired_orders

Parameters

  • order_book: OrderBook that contains the expired_orders
Link to this function

flush_trades!(order_book)

View Source

Specs

flush_trades!(order_book :: order_book()) :: order_book()

Removes all the completed trades from the OrderBook.

Parameters

  • order_book: OrderBook that stores the completed trades
Link to this function

highest_ask_volume(order_book)

View Source

Specs

highest_ask_volume(order_book :: order_book()) :: number()

Returns the sum of the size of all buy orders

Parameters

  • order_book: OrderBook used to sum the size
Link to this function

highest_bid_volume(order_book)

View Source

Specs

highest_bid_volume(order_book :: order_book()) :: number()

Returns the sum of the size of all sell orders

Parameters

  • order_book: OrderBook used to sum the size
Link to this function

insert_order_in_queue(order_book, order)

View Source

Specs

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

Inserts an Exchange.Order in to the queue. The order is pushed to the end of the queue.

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order to be inserted
Link to this function

last_price(order_book, side)

View Source

Specs

last_price(order_book :: order_book(), side :: atom()) :: number()

Returns the lastest price from a side of the order book

Parameters

  • order_book: OrderBook used to search the orders
  • side: Atom to decide which side of the book is used
Link to this function

last_size(order_book, side)

View Source

Specs

last_size(order_book :: order_book(), side :: atom()) :: number()

Returns the lastest size from a side of the order book

Parameters

  • order_book: OrderBook used to search the orders
  • side: Atom to decide which side of the book is used

Specs

open_orders(order_book :: order_book()) :: [Exchange.Order.order()]

Returns the list of open orders

Parameters

  • order_book: OrderBook used to search the active orders
Link to this function

open_orders_by_trader(order_book, trader_id)

View Source

Specs

open_orders_by_trader(order_book :: order_book(), trader_id :: String.t()) :: [
  Exchange.Order.order()
]

Returns the list of open orders from a trader by filtering the orders don't have trader_id

Parameters

  • order_book: OrderBook used to search the orders
  • trader_id: The id that is used to filter orders
Link to this function

order_exists?(order_book, order_id)

View Source

Specs

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

Verifies if an Exchange.Order with order_id exists in the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • order_id: Id to be searched in the order_book

Specs

orders_to_list(queue_of_orders()) :: [Exchange.Order.order()]

Returns the list resulting of flattening a Exchange.OrderBook.queue_of_orders()

Parameters

  • order_book: OrderBook used to search the active orders
Link to this function

pop_order_from_expiration(order_book)

View Source

Specs

pop_order_from_expiration(order_book :: order_book()) :: order_book()

Removes the first element from the OrderBook's experiration_list

Parameters

  • order_book: OrderBook that contains the experiration_list
Link to this function

price_time_match(order_book, order)

View Source

Specs

price_time_match(order_book :: order_book(), order :: 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.

Parameters

  • order_book:
  • order:
Link to this function

queue_order(order_book, order)

View Source

Specs

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

Queues an Exchange.Order in to the correct price_point in the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order to be queued
Link to this function

register_trade(order_book, order, matched_order)

View Source

Specs

register_trade(
  order_book :: order_book(),
  order :: Exchange.Order.order(),
  matched_order :: Exchange.Order.order()
) :: order_book()

Generates a trade and adds it to the completed_trades of the order_book.

Parameters

  • order_book: OrderBook that will store the trade
  • order: Newly placed order
  • matched_order: Existing order that matched the criteria of order
Link to this function

remove_order_from_index(order_book, order)

View Source

Specs

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

Removes the order to the Order Book's order_ids.

Parameters

  • order_book: OrderBook that contains the order_ids
Link to this function

set_ask_min(order_book, order)

View Source

Specs

set_ask_min(order_book :: 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 :: order_book(), Exchange.Order.order()) :: order_book()

Updates the Order Book setting bid_max

Specs

spread(order_book :: order_book()) :: number()

Returns spread for this exchange by calculating the difference between ask_min and bid_max

Parameters

  • order_book: OrderBook that stores the current state of a exchange
Link to this function

stop_loss_activation(order_book)

View Source

Specs

stop_loss_activation(order_book :: order_book()) :: order_book()

This function checks if there are any stop loss orders to activate. If yes then they are converted in market orders, removed and placed on the exchange. ## Parameters

  • order_book: OrderBook to update
Link to this function

total_ask_orders(order_book)

View Source

Specs

total_ask_orders(order_book :: order_book()) :: number()

Returns the number of active sell orders.

Parameters

  • order_book: OrderBook used to search the active orders
Link to this function

total_bid_orders(order_book)

View Source

Specs

total_bid_orders(order_book :: order_book()) :: number()

Returns the number of active buy orders.

Parameters

  • order_book: OrderBook used to search the active orders
Link to this function

update_expired_orders(order_book, order_id)

View Source

Specs

update_expired_orders(order_book :: order_book(), order_id :: String.t()) ::
  order_book()

Fetches the order with order_id and adds it to the Order Book's expired_orders

Parameters

  • order_book: OrderBook that contains the expired_orders
Link to this function

update_order(order_book, order)

View Source

Specs

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

Updates an Exchange.Order in the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • order: Exchange.Order to be updated
Link to this function

update_queue(order_book, side, price_point, new_queue)

View Source

Specs

update_queue(
  order_book :: order_book(),
  side :: atom(),
  price_point :: price_in_cents(),
  new_queue :: queue_of_orders()
) :: order_book()

Updates an Exchange.OrderBook.queue_of_orders() from the Order Book

Parameters

  • order_book: OrderBook that contains the active orders
  • side: The side of the queue
  • price_point: Key to get the queue
  • new_queue: Queue to be updated under the price_point