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:
- http://utilities.optionscity.com/files/freeway/6.3.0/freeway_javadoc/
- http://utilities.optionscity.com/files/widgets/6.3.0/widget_javadoc/
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:
- Subscribe to the message of interest
- Invoke the callback of that message type
- 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.