Skip to main content

XOR Algorithm

Summary

This document describes the XOR algorithm developed in Ember.

XOR stands for X (Crossing) Order Router. This name highlights the nature of this algorithm – it is a combination Smart Order Router logic with an order-crossing matching engine.

Limitations

XOR is not suitable for clients who want to do market making on external venues.

Algorithm logic

The XOR algorithm allows trading on external exchanges or with the other internal orders. It listens on the market data from multiple exchanges and tries to generate trades at the best price for the orders that it receives.

In order to do that, XOR maintains a combined internal order book with quotes from subscribed exchanges and available liquidity from the orders that it receives. It matches new orders with quotes and other internal orders using price, internal/external status, and time priority.

For each matching external quote that it finds, it issues an IOC LIMIT child order targeting the quote. For each matching "resting" internal order, it records a trade and issues corresponding trade events. If a portion of the order remains unmatched, this internal liquidity “rests” in XOR, waiting for either new external quotes or new internal orders.

As the new liquidity becomes available, XOR tries matching all the resting orders again in a FIFO order until either the orders are filled, or they expire based on their time in force.

XOR supports MARKET, LIMIT, STOP and STOP_LIMIT orders with IOC, GTD, GTC time in force.

Configuration

Here is a sample of XOR configuration from the ember.conf configuration file.

XOR: ${template.algorithm.default} { 
factory = "deltix.ember.algorithm.pack.xor.XORAlgorithmFactory"
subscription {
streams = ${marketDataStreams}
symbols = ${contractsList}
}
settings {
orderExpirationTimeout = 30d
marketOrderPriceOffset = 0
feedTopicKey = "l2Feed"
maxRejections = 3
exchangeConstraints = [{
exchangeName = "COINBASE",
acceptsQuoteId=true,
orderTypeDefinitions = [
{orderType = MARKET, timeInForces = [GOOD_TILL_CANCEL, IMMEDIATE_OR_CANCEL, FILL_OR_KILL]}
{orderType = LIMIT, timeInForces = [GOOD_TILL_CANCEL, IMMEDIATE_OR_CANCEL, FILL_OR_KILL]}
{orderType = STOP, timeInForces = [GOOD_TILL_CANCEL, IMMEDIATE_OR_CANCEL, FILL_OR_KILL]}
]
}
]
}
}

Here is the complete list of supported XOR attributes under settings:

Parameter NameDescription
initialActiveOrdersCacheSizeOptional, int. Initial active orders cache size.
initialClientsCapacityOptional, int. Initial client capacity.
maxInactiveOrdersCacheSizeOptional, int. Maximum inactive orders cache size.
recyclingDisabledOptional, boolean, default value is true. Disables recycling of order instance.
orderCacheCapacityOptional, int. Order cache capacity.
feedTopicKeyOptional, string. TB feed topic key.
feedStreamKeyOptional, string. TB feed stream key.
feedMultiDestinationCastAddressOptional, string. Feed multi destination cast address.
validateFeedOptional, boolean, default value is false. When enable validates feed.
maxSnapshotDepthOptional, int. Depth of L2 feed format.
allowSelfTradingOptional, boolean flag, defaults to false. Set to true to allow self-trading.
bookSnapshotIntervalOptional, duration, defaults to 15s. Interval between order book snapshots.
marketClosingTimeOptional, time in hh:mm:ss format, defaults to “16:59:59”. Market closing time.
marketOrderPriceOffsetOptional, int, defaults to 0. For LPs that do not accept quotes market orders are issued as LIMIT orders with limit price capped at % above or below current BBO price.
maxRejectionsOptional, int, defaults to 3. Maximum number of order rejections in a row before LP is marked as disconnected and ignored.
orderExpirationTimeoutOptional, duration, defaults to 30d. Expiration period for GTC orders.
exchangeConstraintsOptional. LP exchanges constraints. Allows specifying order types and the time in force values supported by exchange. See example above. acceptsQuoteId tells XOR whether to include quote id with child order requests.
scheduleOptional. Up-time schedule. XOR will not execute trades or place any new child orders during downtime. See example below.

Schedule example

Here is an example of a schedule that prescribes one hour of downtime from 12 to 1 am on the weekend:

schedule = {
zoneId = "America/New_York"
intervals = [
{
startTime = "00:00:01",
endTime = "00:00:00",
startDay = SUNDAY,
endDay = SATURDAY
}
]
}