Exchange v0.2.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
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 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
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
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
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
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.
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
Specs
completed_trades(order_book :: order_book()) :: [Exchange.Trade]
Returns the list of completed trades.
Parameters
- order_book: OrderBook that stores the completed trades
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
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
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
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
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
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
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
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
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
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
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
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
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
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:
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
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
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
Specs
set_ask_min(order_book :: order_book(), Exchange.Order.order()) :: order_book()
Updates the Order Book setting ask_min
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
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
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
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
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
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