AlgoTraderAlgoTrader Documentation

Chapter 28. Events and Messaging

28.1. Embedded ActiveMQ message broker
28.2. STOPM messaging over WebSockets transport
28.3. Embedded Jetty HTTP server
28.4. RESTful interface
28.5. JSON data binding
28.6. EventDispatcher
28.7. Event listeners
28.8. Strategy life-cycle events
28.9. JMS Destinations

AlgoTrader provides a sophisticated event dispatching and messaging sub system. In Simulation Mode as well as Embedded Mode Event Propagation takes places within the JVM. In Distributed Live Trading Mode Event Propagation from the AlgoTrader Server to the strategies (and between strategies) happens via JMS & ActiveMQ

AlgoTrader makes use of an embedded instance of ActiveMQ message broker for message dispatch and delivery. It presently supports three transports by default:

AlgoTrader employs STOPM messaging protocol over WebSockets transport to implement multi-topic, multi-client message delivery based on the Publish-Subscribe pattern. AlgoTrader acts as a message producer that generates messages representing various system or trading related events and publishes them to predefined topics. Browsers running the HTML5 UI client (and potentially any external application supporting STOMP over WebSockets) act as message consumers that subscribe to message topics of interest such as market data, orders, order status updates, position changes, executed transactions and so on. Consumers express their interest in a particular type of event by subscribing to message topics. Consumers should no longer need to filter out unwanted messages. They are expected to subscribe only to a subset of messages they are interested in.

For further details on the STOMP protocol please visit the STOMP website.

AlgoTrader publishes events to multiple event topics.


Topics are organized by name spaces. A consumer wishing to receive market data for security with id 12 only can subscribe to the following topic:

tick.12

A consumer wishing to receive market data all securities can subscribe to the following wild card topic.

tick.*

Strategy specific events are organized by strategy name. A consumer wishing to receive order status updates for the order with internal id 10 issued by strategy MY_STRATEGY can subscribe to the following topic

order-status.MY_STRATEGY.10

A consumer wishing to receive order status updates for all orders issued by strategy MY_STRATEGY can subscribe to the following wild card topic

order-status.MY_STRATEGY.*

The * wild card selects all elements within the same namespace

A consumer wishing to receive order status updates for all orders of all strategies can subscribe to the following wild card topic

order-status.>

The > wild card selects all topics within the same namespace and their sub-namespaces.

In order to ensure optimal performance of HTML5 clients AlgoTrader can throttle market data event delivered by the WebSockets transport. The embedded message broker by default attempts to ensure that the total rate of events per connection does not exceed 50 per second. At the same time instruments with infrequent market data updates are not throttled if their total event rate is below 0.1 per second (less that one event every 10 seconds).

Throttling rates can be adjusted by changing the following configuration parameters:

activeMQ.maxRatePerConnection = 50

activeMQ.minRatePerConsumer = 0.1

In JavaScript STOMP messages can be consumed like this:

<html>
<head>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"></script>
	<script type="text/javascript">
		var ws = new WebSocket("ws://localhost:61614", "stomp");
		var stompClient = Stomp.over(ws);
		stompClient.connect({}, function(frame) {
			stompClient.subscribe('/topic/tick.*', function(message){
				console.log(JSON.parse(message.body));
			});
		}); 
	</script>
</head>
</html>

For further details please visit the STOMP JavaScript documentation.

In addition to RMI transport AlgoTrader provides a RESTful interface over HTTP/S. RESTful endpoints serve only a subset of AlgoTrader functionality primarily required for HTML5 front-end. While being a subset it nonetheless represents the core functionality of the platform.

HTTP/HTTPS transport is powered by the embedded Jetty HTTP server and REST endpoints are managed by Spring Web framework.

RESTful endpoints largely expose the same interface as Spring services exposed via RMI. REST controllers must follow RESTful semantic and also use immutable value objects for input / output representation.

AlgoTrader RESTful controllers serve several purposes:

The following RESTful controller provides a list of all accounts available in the system:

@CrossOrigin

@RequestMapping(path = "/account", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<AccountVO> getAccounts() {
    return lookupService.getAllAccounts().stream()
            .map(Account::convertToVO)
            .collect(Collectors.toList());
}

In this example the @CrossOrigin annotation marks endpoint as permitting cross origin requests. The @RequestMapping annotation defines various aspects of request / response mapping: path attribute defines path element of the request URI, method attribute defines the request method (such as GET, POST, PUT or DELETE), produces attribute defines expected media type of response body. The endpoint method implementation performs conversion of Account Entity objects to AccountVO objects, which are then serialized to JSON data stream by the framework.

For more detailed explanation of REST controllers and Web annotations please refer to Spring documentation.

The following table contains a list of all REST endpoints. The table uses the following acronyms:

All endpoint URI's start with /rest. For example the full URI for /broker/url/main would be:

http://localhost:9090/rest/broker/url/main

Table 28.2. RESTful endpoints

Endpoint URIVerbInputOutputDescription
/broker/url/mainGET StringReturns the URL of the message broker TCP transport
/broker/url/wsGET StringReturns the URL of the message broker WebSockets transport
/config-paramsGET Map<String, String>Returns a map of configuration parameters.
/cache/clear-allPOST  Clears all internal caches
/securityGET List<SecurityVO>Returns a list of all securities
/security-familyGET List<SecurityFamilyVO>Returns a list of all security families
/security.searchGETqp1: queryList<SecurityVO>Returns a list of security matching the specified query expression or all securities
/forexGET

qp1: baseCurrency (r)

qp2: transactionCurrency (r)

ForexVOReturns a ForexVO value object for the given base and transaction currency pair
/security/{id}GETpp: idSecurityVOReturns a security with the given id
/security-family/{id}GETpp: idSecurityFamilyVOReturns a security family with the given id
/strategyGET List<StrategyVO>Returns a list of all strategies
/accountGET List<AccountVO>Returns a list of all accounts
/account/{name}GETpp: nameAccountVOReturns an account with the given name
/exchangeGET List<ExchangeVO>Returns a list of all exchanges
/positionGET List<PositionVO>Returns a list of all positions
/position/{id}DELpp: id Closes the position with the given id
/position/reduce/{id}POST

pp: id

rb: quantity

 Reduce the position with the given id by the quantity specified
/position/reset-positionsPOST  Resets all positions
/transactionPOSTrb: TransactionVO Records a new transaction with parameters specified in the request body
/transaction/{id}GETpp: idTransactionVOReturns a transaction with the given id
/transaction/dailyGET

qp1: strategy (o)

qp2: limit (o)

List<TransactionVO>Returns all transactions of the current trading day for the specified strategy optionally limited to the specified number of transactions.
/transaction/reset-cache-balancesPOST  Resets all cash balances
/subscription/marketdata/supported-feedGET List<String>Returns a list of all supported market data feeds
/subscription/marketdata/subscribePUTrb: MarketDataSubs..VO Subscribes to the market data feed with parameters specified in the request body
/subscription/marketdata/unsubscribePUTrb: MarketDataSubs..VO Unsubscribes from the market data feed with parameters specified in the request body
/execution/orderGET List<OrderVO>Returns a list of all open orders
/execution/order/{intId}GETpp: intIdList<OrderVO>Returns an order with the given internal id
/execution/order/{intId}DELpp: intId Cancels an open order with the given internal id
/execution/order/marketPOSTrb: MarketOrderVO Submits new market order with parameters specified in the request body
/execution/modify/order/marketPOSTrb: MarketOrderVO Modifies an existing market order with parameters specified in the request body
/execution/order/limitPOSTrb: LimitOrderVO Submits new limit order with parameters specified in the request body
/execution/modify/order/limitPOSTrb: LimitOrderVO Modifies an existing limit order with parameters specified in the request body
/execution/order/stopPOSTrb: StopOrderVO Submits new stop order with parameters specified in the request body
/execution/modify/order/stopPOSTrb: StopOrderVO Modifies an existing stop order with parameters specified in the request body
/execution/order/stoplimitPOSTrb: StopLimitOrderVO Submits new stop-limit order with parameters specified in the request body
/execution/modify/order/stoplimitPOSTrb: StopLimitOrderVO Modifies an existing stop-limit order with parameters specified in the request body
/next-order-idPOSTrb: account id Returns next order id for account with id specified
/runtime/exit-vmPOST  Causes AlgoTrader server to shut down

AlgoTrader uses a consistent message format based on JSON for the event topics described above as well for RESTful endpoints. The use of JSON as a message format and WebSockets / HTTP as transports enables interoperability with a wide variety of modern development platforms and languages.

Using the JSON messages in combination with the AlgoTrader RESTful endpoints and websocket/STOMP topics any popular development language can be used to build trading strategies making use of the AlgoTrader platform, for example:

HTTP GET endpoints can easily be queried via the Browser. To retrieve a JSON formatted list of all accounts open to the following URL in the Browser:

http://localhost:9090/rest/account

In addition one case use Curl, a popular utility for execution of HTTP requests. The following example shows how to retrieve a JSON formatted list of all accounts by executing HTTP GET request:

$ curl -X GET http://localhost:9090/rest/account -i
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.3.6.v20151106)

[{"id":100,"name":"IB_NATIVE_TEST","active":true,"broker":"IB",...},
{"id":101,"name":"IB_FIX_TEST","active":false,"broker":"IB",...},
{"id":103,"name":"DC_TEST","active":false,"broker":"DC",...},
{"id":104,"name":"JPM_TEST","active":false,"broker":"JPM",...},
{"id":105,"name":"RT_TEST","active":false,"broker":"RT",...},
{"id":106,"name":"LMAX_TEST","active":true,"broker":"LMAX",...},
{"id":107,"name":"FXCM_TEST","active":false,"broker":"FXCM",...},
{"id":108,"name":"CNX_TEST","active":false,"broker":"CNX",...}] 

Similarly one can request AlgoTrader to subscribe to market data for security with id 11 by executing HTTP PUT request:

$ curl -X PUT -H "content-type: application/json" 
  http://localhost:9090/rest/subscription/marketdata/subscribe \
  -d "{\"strategyName\":\"SERVER\",\"securityId\":11,\"subscribe\":true}" -i
HTTP/1.1 200 OK
Content-Length: 0
Server: Jetty(9.3.6.v20151106)

The EventDispatcher API represents a platform wide communication interface capable of submitting events to multiple Engine instances and event listeners both inside the same JVM as well as to separated JVM's. The EventDispatcher acts as an event bus for the AlgoTrader platform and individual strategies. The following Recipients are available


EventListener represents a generic communication interface to receive events from multiple event producers both in-process and remote. EventListenerRegistry interface represents a registry of event listeners used internally by the AlgoTrader Server process as well as individual strategy processes. One can register listeners for arbitrary event classes, which enables strategies to generate custom events either through Esper statements or in Java code and consume them internally or propagate them to other strategy processes.

The AlgoTrader platform provides a number of event listeners for common event types such as market data events, order events, external session events, life-cycle events, and a few others. Components that implement those event interfaces which are declared in the Spring application context get automatically registered with the platform upon initialization..

Table 28.4. Standard event listener classes

  
BarEventListenerreceives BarVO events generated from tick events by individual strategies or fed from an external source
EntityCacheEventListenerreceives EntityCacheEvictionEventVO generated by the cache manager
FillEventListenerreceives FillVO events generated by trading interface adapters
GenericEventListenerreceives GenericEventVO events generated by strategies
GenericTickEventListenerreceives GenericTickVO events generated by market data interface adapters or fed from an external source
LifecycleEventListenerreceives LifecycleEventVO generated by the life-cycle manager
OrderCompletionEventListenerreceives OrderCompletionVO events generated by the Server Engine
OrderEventListenerreceives OrderVO events generated by the order service
OrderStatusEventListenerreceives OrderStatusVO events generated by trading interface adapters
PositionEventListenerreceives PositionNutationVO events generated by the transaction service
QueryCacheEventListenerreceives QueryCacheEvictionEventVO generated by the cache manager
QuoteEventListenerreceives QuoteVO events (BidVO or AskVO) generated by market data interface adapters or fed from an external source
SessionEventListenerreceives SessionEventVO generated by market data and trading interface adapters
TickEventListenerreceives TickVO events generated by market data interface adapters or fed from an external source
TradeEventListenerreceives TradeVO events generated by market data interface adapters or fed from an external source
TransactionEventListenerreceives TransactionVO events generated by the transaction service


Life-cycle events signal progression to another phase in the strategy life-cycle and are generated by the platform life cycle manager.

AlgoTrader life cycle manager supports two modes of operation: REAL_TIME and SIMULATION. In both modes all strategies transition through the same life-cycle phases. Depending on the operation mode not all phases may be relevant.


Events are delivered to strategies via JMS. The following JMS Destinations are defined by the system

Since market data events and generic events are pushed into two topics that are available to all strategies, strategies have to select appropriate messages on their own. This is the job of the SubscriptionService. It will modify the selectors on MessageListenerContainer accordingly and invoke the corresponding methods on the (server-side) MarketDataService (e.g. to request market data for additional securities).