Skip to content

1.2 Match Engine

Marc Juchli edited this page Apr 28, 2018 · 8 revisions

Matching engines match buy and sell orders that are submitted to electronic trading networks, like NASDAQ or NYSQ as examples of traditional stock exchanges; or Bitfinex, Bittrex, Coinbase as examples of crypto currency exchanges.

High frequency trading and sophisticated algorithmic trading makes up a substantial part of the participants of the electronic markets. Their servers are oftentimes co-located with the exchanges and specialized computer networks have been constructed to provide millisecond advantage for arbitraging trades between the exchanges. Large institutional traders feel that they are at a disadvantage in such an environment. [1]

This section, however, describes the mechanics of a match engine, which acts as a key component of this project in order to be able to evaluate order placement. Without a local match engine, one would be forced to consult an exchange and either trade on the live market or get access to a test environment. The behaviour of the mentioned participants are taken into account in a later step, by feeding historical data where this behaviour is already embedded.

Types

OrderSide

Implies whether the trader wants to buy or sell a given asset.

OrderSide : BUY | SELL

OrderType

Exchanges provide various order types and therefore allow traders great flexibility to buy and sell assets bound to certain conditions. In our case, consider two of the most commonly used order types:

OrderType : MARKET | LIMIT | LIMIT_T_MARKET

Limit

Arguments:

  • Price
  • Side
  • Quantity

Implies that if the ask price on the opposing side of the book becomes lower or equals (respectively bid price becomes higher or equals, in case of a sell order), the match engine will match those two orders, provided that both parties were the first in line (FIFO), resulting in a trade. The disadvantage of this order type is the uncertainty of whether the order gets executed in the first place. In case no trade from the opposing side appears, the order remains (possibly forever) unexecuted.

Market

Arguments:

  • Side
  • Quantity

Therefore, the market order allows the trader to express his desire to buy (respectively sell) for the best available price. Therefore the matching engine executes trades starting from the price of the opposing side that is closest to the spread, then traverses down the book. Hence, market orders tend to become expensive, especially for large orders.

Order

Allows to define an order to be submitted to the exchange, or in this case directly the match engine, and considered during the matching process.

Order
    side : OrderSide,
    type : OrderType,
    amount : float,
    price : float

Rules

Rules of this match engine are compared to match engines used in real world production very primitive. Further more, the logic is inaccurate and slow, and serves solely to simulate matching of one order from one participant at a time. Hence, the match engine does not provide any queueing of orders and can only provide insight to the question: "How would an order have matched in a certain state of the market in the past."

The rules used by the order matching engine are mainly derived and simplified from [4]:

  • Orders may be partially filled or not filled at all (in the case of a limit order).
  • Market will execute immediately when an opposite order exists in the market.
  • Market orders may be partially filled, at different prices.
  • Limit orders are attempted to be matched at the given point in time, or in case Good Till Time (GTT) is provided, for as long as specified .
  • A Market matching follows the limit matching immediately in case the order type is defined as LIMIT_T_MARKET and the limit matching resulted in no or partial fill.

Implementation

The implementation can be found in match_engine.py.

def matchOrder(self, order, seconds=None)
    """
    Matches an Order according to its type.

    This function serves as the main interface for Order matching.
    Orders are being matched differently according to their OrderType.
    In addition, an optional time interval can be defines from how long the 
    matching process should run and therefore simulates what is generally 
    known as *Good Till Time (GTT)*.
    After the time is consumed, the order is either removed (e.g. neglected) 
    in case of a standard OrderType.LIMIT or a matching on market follows in 
    case OrderType.LIMIT_T_MARKET was defined.

    Parameters
    ----------
    order : Order
        Order defines the will to buy or sell under certain conditions.
    seconds : int
        Good Till Time (GTT)

    Returns
    -------
    [Trades]
        A list of the resulted trades resulted during the matching process.
    float
        Quantity of unexecuted assets.
    int
        Index of order book where matching stopped.
    """
def matchLimitOrder(self, order, orderbookState)
    """
    Attempts to match a limit Order in an order book state.

    Parameters
    ----------
    order : Order
        Order defines the will to buy or sell under certain conditions.
    orderbookState : OrderbookState
        The state of the order book to attempt matching the provided order

    Returns
    -------
    [Trades]
        A list of the resulted trades resulted during the matching process.
    """
def matchMarketOrder(self, order, orderbookState)
    """
    Matches an within an order book state.

    Parameters
    ----------
    order : Order
        Order defines the will to buy or sell under certain conditions.
    orderbookState : OrderbookState
        The state of the order book to attempt matching the provided order

    Returns
    -------
    [Trades]
        A list of the resulted trades resulted during the matching process.
    """

Usage

from orderbook import Orderbook
book = Orderbook()
book.loadFrom...(...)

from order import Order
from order_type import OrderType
from order_side import OrderSide
o = Order(
    orderType = OrderType.MARKET, 
    orderSide = OrderSide.BUY, 
    cty = 1.0, 
    price = 9500.0
)

from match_engine import MatchEngine
engine = MatchEngine(
    orderbook = book,
    index = 0, # Optional: defines index of order book from which to start matching from
    maxRuntime = 100 # Optional: maximum runtime for future executions required for efficiency reasons
)

trades, remaining, index = engine.matchOrder(order=o, seconds=100)

Inspiration taken from https://github.com/IanLKaplan/matchingEngine/wiki/Market-Order-Matching-Engines

  1. Dark Pools: The Rise of the Machine Traders and the Rigging of the U.S. Stock Market, by Scott Patterson, Crown Business, 2012
  2. Eurex: Matching principles. http://www.eurexchange.com/exchange-en/trading/market-model/matching-principles