NOR Algorithm
This document describes the Netting Order Router (NOR) algorithm that can be used for internal netting.
Overview
The NOR algorithm routes its orders to external exchanges. It also matches the orders that it handles with each other and executes internal trades between them. It routes the orders either according to an explicit target exchange, specified with order parameters, or determines a destination automatically, based on the configured auto-routing rules.
NOR maintains an order book with its active internal orders and, when configured to give the best price priority, it tries to match its internal orders with each other at the price that is not worse than the price available on the external exchanges targeted by these orders.
NOR supports MARKET IOC orders and LIMIT orders with IOC, GTD, GTC, and DAY time in force conditions.
Order Processing Logic
The NOR algorithm keeps its active orders sorted by limit price and then by submission time.
Orders received by NOR are validated and then matched with the active internal orders on the other side of the market using price and submission time as the priority.
When there is no internal match, the processed order is placed with the external exchange. NOR places the order to an exchange by issuing a corresponding order to the exchange with the same parameters. This new order is called a child order and the original order received by NOR is its parent order. NOR keeps track of the child order and cancels it when the parent order expires according to its time-in-force parameter. If the child order placed to exchange is filled or canceled by the exchange, NOR sends corresponding events to the client. After the internal order is placed to the external exchange like that, its initial processing is finished and the order is “resting”.
When there is an internal match with another order that is already “resting” on an exchange, NOR does the following:
- Issues an IOC LIMIT child order for the received order quantity. The limit price is set to be one tick better than the matched resting order limit price. This IOC order is intended to take out any liquidity available on the exchange at a price better than the other internal order limit price.
- After the IOC child order is filled or canceled and there is remaining quantity, NOR pulls the matching resting order from the exchange by either canceling or replacing it to free up just the required quantity.
- After the resting order is pulled from the exchange, NOR records a trade between the two internal orders.
If after these steps, the processed order is still not filled, NOR proceeds matching it with the next best resting order as described above.
Each order processing is finished when the order is either filled or its remaining quantity is placed to exchange.
Any other order arriving while the first order is being processed is acknowledged with thePENDING NEW ORDER
event and
the order is placed into the queue. After order processing is finished, NOR picks the next order from the queue
for processing and notifies the client with the NEW ORDER
event.
Order Modification
Parent orders can be modified with price and size changes. Upon submitting an order modification, any existing child order is pulled back from the external market. If this is successful, then the modified order is placed to NOR and NOR proceeds with checking if the order is internal only or not, and if it can be matched with any existing internal order. Subsequent child orders may then be sent.
Examples
Let's say we have a BUY 5 @ 10
internal order resting on an exchange. And the current best bid on the exchange is BUY 1 @ 11
.
Then NOR receives a SELL 10 @ MARKET
order.
In this case, the algorithm does the following:
- Issues an IOC LIMIT order to
SELL 10 @ 10.1
(assuming 0.1 is the tick size for the instrument) and waits for response from exchange. The IOC order trades1 @ 11
and then the remaining 9 is canceled. - Issues a Cancel request for a
BUY 5 @ 10
order to pull the resting order from the exchange. After the order is canceled, these two internal orders trade5 @ 10
. - Issues a
SELL 4 @ MARKET IOC
order for the remaining quantity. - After the order is canceled by exchange, since there is no more market, the remaining 4 quantities of the parent SELL order are canceled as well. The
SELL 10 @ MARKET
order is partially filled with1 @ 11
and5 @ 10
.
Limitations
- Cancel Replace requests are rejected for the order that is being processed. Replace is allowed for the resting orders and for the orders that are still waiting in the queue.
- In the case of an Ember server restart, NOR cancels all the active child orders first and then processes all the active parent orders in the order they were submitted. It rejects any new requests for some period after restart, until it successfully cancels all the active child orders and starts order processing. The restart procedure considers the already executed portion of each active order and resumes execution of the remaining amount.
Custom ORDER ATTRIBUTES
These additional order attributes can be set via C3Trader or Ember Monitor with the new order:
Attribute Name | Attribute Key | Description |
---|---|---|
Internal Only Flag | 6040 | Set to True to prevent external child orders. |
External Destination | 6041 | Set to Destination to manually route child orders. Can be used during order modification to change internal orders to external. |
Only one of these attributes can be active at any point in time.
Configuration
Here is a sample of NOR configuration from the ember.conf configuration file.
NOR: ${template.algorithm.default} {
factory = "deltix.ember.algorithm.pack.nor.NORAlgorithmFactory"
subscription {
streams = ${marketDataStreams}
symbols = ${contractsList}
}
settings {
orderExpirationTimeout = 30d
marketClosingTime = "16:59:59"
timeZone = "America/New_York"
internalMatchPriority = false
}
}
Here is the complete list of the supported NOR attributes under settings:
Parameter Name | Description |
---|---|
initialActiveOrdersCacheSize | Optional, int. Initial active orders cache size. |
initialClientsCapacity | Optional, int. Initial client capacity. |
maxInactiveOrdersCacheSize | Optional, int. Maximum inactive orders cache size. |
recyclingDisabled | Optional, boolean, default value is true. Disables recycling of order instance. |
orderCacheCapacity | Optional, int. Order cache capacity. |
internalMatchPriority | Optional, boolean, false by default. Indicates that NOR should prioritize internal orders when matching over price, i.e., it does not try to trade externally at a better price if internal matching liquidity is available. |
marketClosingTime | Optional, time in hh:mm:ss format, defaults to “16:59:59”. Market closing time. |
timeZone | Optional, time zone for the market closing time, defaults to "America/New_York" |
orderExpirationTimeout | Optional, duration, defaults to 30d. Expiration period for GTC orders. |
allowSelfTrading | Optional, boolean, defaults to false. When true, orders are not rejected because of self-trading. |
validateFeed | When enabled, the matcher uses a (slow) Data Validator of the market data feed published to the feed stream/topic. |
feedTopicKey | Topic to broadcast market data. |
feedStreamKey | Optional TimeBase stream with broadcasted L2 market data showing the current state of the NOR order book. |
feedMultiDestinationCastAddres | When provided in context of a feed topic, this setting is used to create a Multi-Destination-Cast Aeron publication. |
externalFeedStream | Optional TimeBase stream with broadcasted L2 market data about child orders issued by NOR to external exchanges. Entries in this stream have compound exchange IDs that look like NOR-BINANC (limited to 10 characters). |
bookSnapshotInterval | Interval at which an OB snapshot is published. |
maxSnapshotDepth | Maximum OB snapshot depth. |
routingRulesStream | Optional TimeBase stream with auto-routing rules. |
ownerStream | Optional TimeBase stream with instrument owner or MA trader data. |
tradesStream | Optional TimeBase stream with broadcasted L3 market data about all (internal and external) trade events. |
Auto-routing
Auto-routing is enabled via setting the routingRulesStream
parameter in the NOR configuration in ember.conf.
settings {
orderExpirationTimeout = 30d
marketClosingTime = "16:59:59"
timeZone = "America/New_York"
routingRulesStream = NORRoutingRules
}
The routingRulesStream
points to a TimeBase stream that contains auto-routing rule messages. Each message contains
a list of rules for the same symbol. Each rule has attributes that are used to match it to the order
and specifies a target exchange. Each rule has the following attributes:
Column Name | Description |
---|---|
trader | Order Trader is matched to this value. Can be null. |
traderGroup | Order TraderGroup are matched to this value. Can be null. |
maxBuyQuantity | Maximum Buy Quantity – Orders with a quantity above this amount are not auto routed. Can be null. |
maxSellQuantity | Maximum Sell Quantity – Orders with a quantity above this amount are not auto routed. Can be null. |
maxPriceSpread | Maximum Price Spread (% value) – Order limit price is compared against Best Bid (for Buys) and Best Ask (for Sells). Can be null. |
maxAbsolutePriceSpread | Maximum Price Spread (absolute value) – Order limit price is compared against Best Bid (for Buys) and Best Ask (for Sells). Can be null. |
maxExternalOrders | Allowed # of external orders for this rule. If the maximum is reached, then no further external orders are sent. Once an external order is completed, the existing internal orders are reevaluated to see if they can now submit an external order. |
exchangeId | Orders that match symbol/trader/traderGroup and are within Quantity and Price are automatically routed to this Exchange. |
NOR selects the rule that applies to the order by the matching trader
and traderGroup
attributes to the order and verifying that
the order also satisfies the limits set in the rule.
Null values in the rule are interpreted as wildcards and match any value. When matching an order, NOR selects the best matching rule with an explicit trader or traderGroup value match taking priority over a match via a wildcard (null). It then evaluates the limits in the rule, and if all of them are satisfied by the order, the order is routed to the exchange specified by the rule. If no matching rule is found, the order is routed to an external exchange and is handled as an internal-only order.
Routing Cases
Auto-routing is only applied to non-internal-only orders that do not explicitly set the internalOnly
attribute 6040 to true.
UI Values | Child Order | ||||
---|---|---|---|---|---|
Destination | Exchange | AutoRouting | Rule Matched | Destination | Exchange |
NOR | blank | Enabled | TRUE | Rule | Rule |
NOR | blank | Enabled | FALSE | N/A | N/A |
NOR | blank | Disabled | NOR default destination | SMD /Default exchange | |
NOR | TRAYPORT | Enabled | TRUE | Rule | TRAYPORT |
NOR | TRAYPORT | Enabled | FALSE | N/A | N/A |
NOR | TRAYPORT | Disabled | NOR default destination | TRAYPORT |
External child orders
These are the steps the NOR algorithm takes to determine if and when an external child order is submitted:
- Whenever a new or replace parent order is submitted to NOR, it is first checked to see if it is internal only or can be routed externally. This is based on the
internalOnly
flag and the auto-routing rules. Auto-routing rules are matched by matching the parent orderSymbol
andTrader
/TraderGroup
values against the rules.- If no match is found, the order stays internal and no child order is sent.
- If a matching rule exists, the parent order is validated against Rule Size and Price limits.
- If not within Size/Price limits, no child order is created and the order stays internal.
- If within Size/Price limits, then child orders can be created. These would be sent to the Destination marked in the Rule Exchange value.
- After this determination, it is then checked to see if the order can be matched internally.
- If it is matched internally:
- If the
internalOnly
flag is set to true or no valid Auto-routing rule was matched, the order will only exist on the internal market and no external child orders are created. The order is matched internally, and the remaining quantity rests on the internal market. - If the
internalOnly
flag is set to false and a valid Auto-routing rule was matched:- If internalMatchPriority = false, then the IOC child order is first sent to an external Destination to try to get the best price. Any remaining quantity is then matched internally. If there is still a remaining quantity, an additional child order is sent externally.
- If internalMatchPriority = true, then the order is matched internally. If there is still a remaining quantity, then an additional child order is sent externally.
- If the order is not matched internally:
- If the
internalOnly
flag is set to true or no valid Auto-routing rule was matched, the order only exists on the internal market and no external child orders are created. The order rests on the internal market. - If the
internalOnly
flag is set to false and a valid Auto-routing rule was matched, the child order is sent to an external destination.
Instrument Owner
The ability to automatically set a different Trader on external child orders is done via the ownerStream
parameter in the NOR configuration in ember.conf.
Stream messages specify an instrument owner and Market Access (MA) traders:
Column Name | Description |
---|---|
symbol | Instrument symbol |
owner | Optional symbol owner |
maTraders | Optional comma separated list of MA traders for this symbol |
If this option is disabled, orders are not routed to external exchanges. Whenever a child external order is created, NOR sets the order Trader attribute according to the value in the configured owner stream as follows:
- If a parent order trader is among t he MA traders, this trader is used for the child order.
- Otherwise, we’ll set it to the stream owner. If the owner is not specified, the order is not routed externally.
When the MA trader for an instrument changes, any resting orders affected by this change are pulled from the external exchange and continue to be treated as internal-only orders.