AlgoTraderAlgoTrader Documentation

Chapter 27. Events and Messaging

27.1. Embedded ActiveMQ message broker
27.2. STOPM messaging over WebSockets transprot
27.3. Embedded Jetty HTTP server
27.4. RESTful interface
27.5. JSON data binding
27.6. EventDispatcher
27.7. Event listeners
27.8. Standard event listener classes
27.9. Strategy life-cycle events
27.10. JMS Destinations
27.11. JMS Configuration

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

As of version 3.0 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.

AlgoTrader publishes events to multiple event topics.


Topics are organized as 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 wildcard topic.

tick.*

Strategy specific events are organized by strategy name. A consumer wishing to receive order status updates for 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 wildcard topic

order-status.MY_STRATEGY.*

The * wildcard 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 wildcard topic

order-status.>

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

Note

Please note that 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 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

As of version 3.0 in addition to RMI transport AlgoTrader provides RESTful interface over HTTP/S. At the moment 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 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 however must follow RESTful semantic and also use immutable value objects for input / output representation.

AlgoTrader RESTful controllers serve several purposes:

@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 accronyms:

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 27.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:

The following example demonstrates interaction with the AlgoTrader platform using Curl, a popular utility for execution of HTTP requests available for most common operating systems.

The following example demonstrates how one can query all existing accounts in the AlgoTrader database by executing HTTP GET request:

$ curl -X GET http://myhost: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://myhost: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.


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..


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.


The following JMS Destinations are defined by the system

The entire JMS subsystem is configured through the following Spring Configuration files.

applicationContext-messaging.xml:

applicationContext-remote.xml:

applicationContext-client-xxx.xml:

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).