Skip to main content

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 messageReason
Ask / Bid quote is not activeThe order quote was found but Ask or Bid price quote is no longer available
Quote is no longer activeQuote ID specified in the order cannot be found
Quoted price mismatchOrder limit price does not match the price in the quote referenced by the order
Quoted size mismatchOrder size does not match the size in the quote referenced by the order
Only previously quoted orders are supportedOrder 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 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.
streamKeyOptional, string, defaults to "rfq". TB stream for sending and receiving RFQ messages
defaultOrderDestinationOptional, string, defaults to null. When specified used as destination for child orders
quoteMarginOptional, double, defaults to 5.0. Margin % added to the quoted prices
quoteExpirationTimeoutOptional, duration, defaults to 20s. Quotes expiration timeout after which request quotes will be updated
quoteRequestExpirationTimeoutOptional, duration, defaults to 2m. Quote request expiration timeout after which request quotes will be canceled
issueFOKOrdersOptional, boolean, defaults to false. When enabled RFQ Algorithm will always use FOK Time In Force for child orders