Event Handling and Conflation

In this section we go futher in to the concept of event handling. Freeway is an event driven API and so concepts addressed here should be considered in successful implementation of custom algorithms.

JavaDoc and Freeway API organisation  

For your reference, the Freeway and Widget API JavaDocs can be found here:  

In this section we focus on the Freeway API in the context of Freeway jobs (defined as classes which are extensions of AbstractJob). The Freeway API is divided into 6 main packages:

  • freeway.api - general objects within the API 
  • helpers - helping classes for pricing and formatting usually abstracted from the user. 
  • jobs - shows different types of Freeway jobs (see Session 4) 
  • messages - shows all different message types 
  • playback - playback and back-testing objects listed here 
  • services - probably the most important package - contains methods to interact with the system, affect the state of the system and get information about the system from a Freeway job.

Events and Messages

In general, Freeway is an event driven API. The users subscribes to a particular event type and then implements the corresponding event handler. 

There are many types of message generated by intrinsic or extrinsic events (see package com.optionscity.freeway.api.messages in JavaDoc). Metro can take data from many exchanges however the internal messages are all normalised into various types. These include: 

Market data events eg. : 

  • AuctionMessage - an auction (request for price) message 
  • BookDepthMessage - market message when book depth changes 
  • RequestForQuoteMessage - request for quote 

    System events eg.: 

    • ConfigurationChangeSignal - a signal sent when the job configuration is changed while running 
    • GridChangeSignal - signal sent when a grid change is requested 
    • JobStarted - a signal sent when a job instance is started

    Safety events eg: 

    • TradeRisk Signal - sent by the system when a trade risk (too many trades) is encountered. 
    • MarketRisk Signal - sent by the system when a market risk (e.g. exchange QPS, protocol error), etc.) is encountered. 

     In general, the job container sends a message to a job upon an event taking place. 

    Just to clarify nomenclature, we ask the question the difference between messages and signals? We would conventionally relate a message to a market data event and signals to an internal Metro event. The user can extend the Signal class to make instances of custom signals (addressed in Session III). Both are in the same package with respect to the API (api.messages). 

    Subscribing to messages 

    The usual job design will involve the following steps: 

    1. Subscribe to the message of interest
    2. Invoke the callback of that message type 
    3. Utilise the Freeway Container service to access or change Metro data/analytics. 

    All message subscriptions are done via methods in the container object called in the begin() method. A typical example is below: 

    public void begin(IContainer container){
    super.begin(container);
    container.subscribeToOrderMessages(); // Subscribe to OrderMessages
    }

    There are a host subscribe methods in the container for each message type: 

    Method 

    Detail 

    subscribeToAuctionMessages() 

    Tells the container to send any auction (request for price) notifications to this job. 

    subscribeToBookDepthMessages()  

    Tells the container to send any book depth update notifications to this job. 

    subscribeToInstrumentMessages() 

    Tells the container to send any instrument notifications to this job. 

    subscribeToMarketBidAskMessages()  

    Tells the container to send any BidAsk notifications to this job. 

    subscribeToMarketStatsMessages()  

    Tells the container to send any market statistics notifications to this job. 

    subscribeToOrderMessages() 

    Tells the container to send any order notifications to this job 

    subscribeToQuoteMessages() 

    Tells the container to send any quote messages to this job 

    subscribeToRequestForQuoteMessages() 

    Tells the container to send any RFQ notifications to this job 

    subscribeToSignals() 

    Tells the container to send any signals to this job 

    subscribeToTheoMessages() 

    Tells the container to send any theoretical data notifications to this job 

    subscribeToTradeMessages() 

    Tells the container to send any trade notifications to this job 

    If the user subscribes to an event then they must then implement the appropriate callback for that event in the main Job class. 

    Method 

    Detail 

    onAuction(AuctionMessage msg) 

    Called upon an auction event in the server. 

    onBookDepth(BookDepthMessage msg) 

    Called upon change to market book depth.  

    onInstrument(InstrumentMessage message) 

    Called when the server receives a new instrument or an instrument update 

    onMarketBidAsk(MarketBidAskMessage msg) 

    Called when a BidAsk  

    onMarketLast(MarketLastMessage msg) 

    Called upon change in market data  

    onMarketStats(MarketStatsMessage msg)  

     Called upon change in market statistics data. 

    onOrder(OrderMessage msg)  

    Called when upon an order event in the server. 

    onQuote(QuoteMessage message)  

    Called when quote data is generated by the server. 

    onRequestForQuote(RequestForQuoteMessage msg) 

    Called upon RequestForQuote event in the server. 

    onSignal(Signal signal)  

    Called upon any generated Signal event for this job. 

    onTheo(TheoMessage msg) 

    Called upon change theoretical data. 

    onTrade(TradeMessage msg)  

    Called when a trade is executed on the server. 

    In the context of the above example an implementation would look like this: 

    public void begin(IContainer container){
    super.begin(container);
    container.subscribeToBookDepthMessages();
    }

    public void onBookDepth(BookDepthMessage msg){
    // Do something here
    }

    Messages are light-weight objects which usually contain only information to tell that an event has happened eg consider the MarketBidAskMessage. This message is sent by the container to the job when bid or ask changes. This message contains only the following fields: 

    instrumentId, seqnum, machine, timestamp, priceChange 

    ie. does not contain the actual market bid or ask for that instrument. In order to access the actual market pricesthey must be accessed through one of the relevant Freeway services (described in the next chapter). These services are usually accessed through convenience methods within the AbstractJob instruments() accesses the Instrument service to retrieve the market prices. 

    public void begin(IContainer container){
    super.begin(container);
    container.subscribeToBookDepthMessages();
    }

    public void onBookDepth(BookDepthMessage msg){

    Book myBook = instruments().getBook(message.instrumentId);

    // instruments() is the convenience method that references the job container's IInstrumentService

    // Do something with myBook eg.

    for (int i=0 ; i < book.bid.length ; i++) {
    Book.BookEntry bidEntry = book.bid[i];
    log("Bid price:" + bidEntry.price);
    }

    for (int i=0 ; i < book.ask.length ; i++) {
    Book.BookEntry askEntry = book.ask[i];
    log("Ask price:" + askEntry.price);
    }
    }

    Conflation

    The following events are conflated if the system is unable to process the events as they come in ensuring that the code will receive the most recent update.

    Event
    Event Handler
    Market Bid/Ask Event onMarketBidAsk(MarketBidAskMessage m)
    Theoretical Event onTheo(TheoMessage msg)
    Book Depth Event onBookDepth(BookDepthMessage msg)
    Quote Event onQuote(QuoteMessage message) 

    The following events are NOT conflated:

    Event
    Event Handler
    Request For Quote Event 

    onRequestForQuote(RequestForQuoteMessage msg)

    Order Event onOrder(OrderMessage msg)
    Trade Event onTrade(TradeMessage msg)
    Signal Event onSignal(Signal signal)

    NB. Signals are not conflated, so they are not a recommended way to send realtime trading values in very active instruments because any queuing could result in stale signals arriving at your job.