RFQ Algorithm
Summary
RFQ Algorithm can be used to add quoting capability to market venues that do not support it natively. It can handle quote requests, generate quotes based on the current order book, and forward previously quoted orders issued for the active quotes returned by the algorithm.
Description
RFQ Algorithm will subscribe to the market data streams specified in its config and maintain an order book based on this
data. It will use configured TB stream for receiving quote requests and sending back quotes.
The QuoteRequest, QuoteInfo messages in this stream are from deltix.timebase.api.messages.rfq
package of deltix.qsrv:deltix-timebase-api-messages
library.
When the new quote request is received, algorithm will generate a response with the quotes according to the current bids and asks in the order book:
- if request does not specify quote side, algorithm will try to come up with both bid and offer quotes. Otherwise, only quote for the request side will be generated
- if request does not specify quote quantity, algorithm will quote the best bid/offer from the order book
- if request has quantity and there is enough liquidity in the order book, algorithm will generate a quote based on multiple best quotes
- if order book does not have enough liquidity for a quote the quote in the response will have 0 value for the price and quantity
The prices of returned quotes will be marked up according to the configured quote margin %.
If no quotes can be generated for the quote request, algorithm will send quote reject message with "No market" as the reject reason.
RFQ Algorithm will keep track of active quote requests and update their quotes every time they expire according to configured quote expiration timeout. When request itself expires after configured quote request expiration timeout, algorithm will remove it and send the quote cancel message to the client.
RFQ Algorithm will handle only previously quoted orders and reject any other order requests. It will validate new order requests and reject them if:
- Quote is no longer active (timed out or cancelled)
- Order size doesn't match quoted quantity
- Order price doesn't match quoted price
After order is validated RFQ Algorithm will issue a corresponding child LIMIT order to the configured target exchange. If issueFOKOrders setting is enabled in the config this child order will have FillOrKill Time In Force. Other than that, it will inherit all the attributes of the parent order.
After issuing child order algorithm will then act as a proxy and forward any events received back from the exchange. So the order could still be rejected by the target exchange due to one of these reasons:
- Loss of connectivity to the target exchange.
- Target exchange rejects order due to incompatible order parameter or some other reason (e.g. trading balance, etc.).
The order is not guaranteed to be filled in this case, since RFQ algorithm is simply forwarding the order to the target exchange and the price on the target exchange could have moved away beyond quote margin price or there is not enough liquidity to immediately fill the order anymore.
Order reject messages:
Reject message | Reason |
---|---|
Ask / Bid quote is not active | The order quote was found but Ask or Bid price quote is no longer available |
Quote is no longer active | Quote ID specified in the order cannot be found |
Quoted price mismatch | Order limit price does not match the price in the quote referenced by the order |
Quoted size mismatch | Order size does not match the size in the quote referenced by the order |
Only previously quoted orders are supported | Order must have PREVIOUSLY_QUOTED order type |
Configuration
Sample RFQ algorithm configuration from the ember.conf configuration file:
RFQ: ${template.algorithm.default} {
factory = "deltix.ember.algorithm.pack.rfq.RFQAlgorithmFactory"
subscription {
streams = ${marketDataStreams}
symbols = ${contractsList}
}
settings {
streamKey = "rfq"
defaultOrderDestination = COINBASE
quoteMargin = 5.0
quoteExpirationTimeout = 20s
quoteRequestExpirationTimeout = 2m
issueFOKOrders = true
}
}
Complete list of supported RFQ 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. |
streamKey | Optional, string, defaults to "rfq". TB stream for sending and receiving RFQ messages |
defaultOrderDestination | Optional, string, defaults to null. When specified used as destination for child orders |
quoteMargin | Optional, double, defaults to 5.0. Margin % added to the quoted prices |
quoteExpirationTimeout | Optional, duration, defaults to 20s. Quotes expiration timeout after which request quotes will be updated |
quoteRequestExpirationTimeout | Optional, duration, defaults to 2m. Quote request expiration timeout after which request quotes will be canceled |
issueFOKOrders | Optional, boolean, defaults to false. When enabled RFQ Algorithm will always use FOK Time In Force for child orders |