The Gateway to Algorithmic and Automated Trading

MTS BondsPro API: Opening New Doors

Published in Automated Trader Magazine

MTS Markets International Inc. is the US subsidiary of the MTS Group. In the US corporate bond space they manage an ATS called BondsPro (formerly known as Bonds.com). While a screen-based version of MTS BondsPro has been available for some time, a more recent innovation has been the introduction of an API. Aly Kassam, CEO of Quantitative Support Services, and Andy Webb, founder of Automated Trader magazine, took it for a spin.

MTS BondsPro's API uses FIX 4.4 [1] to enable market participants to create machine to machine interfaces that can be used for a range of trading activities, including submitting bids and offers to the trading platform, obtaining price data, hitting/lifting quotes, retrieving trade execution reports and receiving post-trade STP messages.

The platform's use of the FIX protocol opens the door to a wide range of trading and market making activities. MTS BondsPro requires that all participants are Qualified Institutional Buyers (as defined in Rule 144a of the Securities Act of 1933). As a result, programming and technology resources are unlikely to be an issue for the majority of participants. Having said that, the API's use of FIX and the availability of the popular open source QuickFIX FIX engine means that it is also readily accessible by those with more modest technological budgets.

Apart from general efficiency, one interesting possibility is that a combination of MTS BondsPro's API and a suitable analytical/trading application makes a new automated take on existing inter market arbitrage strategies possible. For instance, many now regard convertible arbitrage as rather played-out because of over-participation. However, another factor in this situation is the low frequency in which convertible arbitrage has historically operated, partly because of the delays inherent in accessing the fixed income leg from voice brokers, which has effectively reduced the strategy's capacity. A combination of the right analytical/trading platform and the MTS BondsPro's API significantly changes this status quo. Intraday convertible arbitrage opportunities inaccessible (even invisible) to those using voice brokers become available, as does any other arbitrage strategy involving a bond leg.

Nevertheless, it is important to stress that this is not an API for high-frequency trading in the sense often applied to futures exchanges (market dynamics in fixed income simply make that impossible). But it is well-suited to "mid-frequency" automated trading, both on just the BondsPro platform and in combination with other markets such as equities.

Test procedure

For the purposes of this review we opted for the Java version of QuickFIX, QuickFIX/J, though we could just as easily have used the .NET version, QuickFIX/n (although this is less mature technology). Armed with this, we set ourselves the task of building a complete bilateral connection between MTS BondsPro and MATLAB. This would enable sophisticated modelling, testing and potentially also (for lower activity strategies) live trading from within MATLAB.

[1] MTS Bonds.com is also compatible many OMS/EMS systems and third party software vendors.

Java code

The first stage of the Java coding was to write the data and trade handlers. In the case of the data handler, the initial step was to write a class that implemented the QuickFIX application interface. This guarantees that certain programming methods will be derived and available from the application interface (see Figure 1 for the first few of these methods) .

Figure 1

It's not obligatory to use all these methods, but they have to be present in the code (even if only as placeholders) for everything to work properly. The most important method from our perspective was fromApp (second method shown in Figure 1) which is a callback that receives all the messages from MTS BondsPro and is used to invoke the crack method, which inherits from the QuickFIX MessageCracker method (see line 32 of Figure 1).

As its name implies, the crack method cracks open the message, splits it into its component parts and creates a Java object containing the various fields and values. By using the QuickFIX dictionary, one can decode the various elements from the QuickFIX message numbers. For example number 8 is the begin string, number 35 the message type. In the case of MTS BondsPro the message type is X, which is a market data incremental refresh.

Figure 2



The Java object created by the cracker is then passed down to the overloaded onMessage method (see Figure 2) . At this point we encountered something we weren't expecting. Our assumption was that MTS BondsPro's market data feed would be based on a subscription model, whereby streaming data on individual instruments are requested from the server, so the server only sends data for the instruments requested.

Wrong. In the case of MTS BondsPro, you make a data connection and you receive everything [1], which when we first opened the connection was 200,000 messages in the first 20 minutes of a trading session. For larger participants this isn't an issue, as it is likely that they will simply stream this into a high performance database engine and then redistribute from there as appropriate to various desks. However, for smaller participants that might be connecting to a single application as we were, it seemed at first glance a potential problem.

The first stage in dealing with the data is straightforward: write code that only processes data for which you are subscribed, otherwise discard the message (see Figure 3).

[1] A subscription based alternative to receiving MTS BondsPro data is currently in development.



Figure 3



If the data is for a subscribed instrument, then the next step is to extract the desired data from the Java object ( see lines 125 to 132 of Figure 3). Then the event can be broadcast to all listeners (see line 134 and onwards of Figure 3).

The next stage is where we originally thought there might be an issue. Originally (see commented out line 136 of Figure 3) we were simply finding the listener and calling an update method in MATLAB to receive the data. However, that meant the Java thread had to wait for MATLAB to process the data before it could revert to Java. For a small number of instruments (or a larger number of inactive instruments) this wouldn't be an issue, but once instruments and data rates increased it would cause a backlog and errors.

In practice, there's a simple way round this, which means that MTS BondsPro can readily be used without this sort of issue even when connecting to individual applications that might take a while to process updates. The solution is to create a service that uses a pool of worker threads to which the original Java thread passes the task. This allows the main Java thread to go back to connecting and processing messages, leaving the worker thread from the pool that was assigned the task to deal with the client application (in our case MATLAB). We created a pool of 50 worker threads to deal with MATLAB, which was more than sufficient for our purposes, but this could be scaled up to any number.

The key point is that this makes streaming data from MTS BondsPro to a single application (even for a large number of active instruments) completely feasible.

MTS BondsPro's MarketDataIncrementalRefresh message is pretty rich, with 17 tagged fields. While most of these are fairly standard (bid/offer, price, CUSIP/ISIN etc) some are of particular relevance to those looking to automate their trading via an API. For instance, the 6373 tag (Firmness Indicator) indicates whether the order is Auto-Execute ("Firm", flag "F") or not ("Subject", flag "S").

The approach we used for trade handling was very similar to that used for data. Again it implements the QuickFIX application interface and inherits from the QuickFIX message cracker to convert FIX messages into Java objects. The first few methods are identical to those used for data handling (fromAdmin, fromApp etc).

While message rates will be much lower than for market data (as you'll only be sending/receiving messages relating to trades), unlike market data (where there is only the X type market data incremental refresh message type) there are potentially 12 different trade message types with which to deal. Another obvious distinction is that all messages will be relevant as they relate to trades, so there is no need for a discard mechanism. By the same token, unless you have very high trade volumes, there is no need for a pool of worker threads.


Interface with MATLAB

The approach we used for creating the MATLAB interface was fairly generic and so would be applicable for most applications. It involves three steps:

  1. Defining Java interfaces to QuickFIX, listing the callbacks to be exposed to MATLAB
  2. Writing code that allows external users (in this case MATLAB) to subscribe or unsubscribe from these interfaces
  3. Then (for simplicity) defining a class that wraps up all the data for the callback into a single object. (This is the object that is pushed into the external application (in our case MATLAB)

Figure 4



MATLAB code

While the code written to process data and trades in MATLAB was obviously specific to MATLAB, the approach is more generally applicable. So for obtaining market data, the starting point was a brief MATLAB script that set up the data feed by creating a FixDataStream object containing a list of instruments to which we wished to subscribe. The object was then passed a QuickFIX configuration file, which among other things contained the logon credentials to MTS BondsPro (see Figure 4 for both files - DataStreamScript.m and fixdatastream.cfg).

At first were slightly mystified by the port settings specified for the API connection, which appeared to be port 80 for both data and trading, but in practical terms this isn't actually the case . In fact there is a router sitting in front of the MTS BondsPro servers that reads all incoming messages, and based upon whether they contain trading or data log on credentials, re-routes them to the appropriate trading/data server.

The choice of port 80 as the only port required for connection to MTS BondsPro actually makes a great deal of sense. At a stroke, it avoids all the difficulties and delays associated with opening non-standard firewall ports in large financial organisations (because port 80 is also the standard HTTP port), thereby helping to cut deployment times.

We built a class (FixDataStream) that inherits from a parent class we also created called FixConnection, which in turn inherits from a MATLAB handle (which is the equivalent of a reference class)[1]. This allowed us to connect, disconnect and send messages to the MTS BondsPro API from MATLAB. For testing, we configured the class to save the most recent 500 data points for each instrument in an array, but obviously this could be larger and/or contain logic to write to a database file.

To avoid duplication, the same FixConnection we created could also be used for trading activity by a TradeHandler class we wrote. This is then passed a QuickFIX configuration file that is essentially identical to our fixdatastream.cfg file mentioned above, except that it contains trading rather than data retrieval logon credentials.

As its name implies, the TradeHandler class allows us to place new orders, cancel or cancel/replace orders and receive information about orders. In order to manage trades after placement, we use the Java unique user ID to generate a unique trade ID that we could use for actions such as cancelling orders.

One important point is that if you wish to place market orders from any automated trading application, you will need to create them synthetically, because MTS BondsPro does not offer native support for them. A section of code that submits a limit order flagged as fill or kill (FOK), checks for a fill, and if none has taken place, does a cancel replace FOK (with a suitably adjusted price) would suffice.

Conclusions

Bottom line: the MTS BondsPro API does everything it says on the tin. Once we were up and running, everything worked as it should. Furthermore, despite the potentially large volumes of data involved, there is no reason why the API cannot be used to connect even to lower performance applications that use interpreted rather than compiled languages. (Any potential bottlenecks can be avoided by using the pool of worker threads technique we used, or similar, and this would also be possible if using .NET.) The fact that we were able to use QuickFIX successfully to make the connection also means that software costs can be kept to a minimum.

[1] MATLAB handles have the ability to listen for and subscribe to events, such as those raised in our Java class.


During testing, we encountered one issue that related to mistiming of FIX messages (e.g. messages appearing to originate in the future). This turned out to be caused by an NTP time server that had failed to restart, which MTS quickly corrected. As we were operating in the user acceptance testing rather than production environment, this was not a major crisis.

Even though the majority of API users on the platform will probably have ample tech resources, in an ideal world the documentation would include some example code fragments and error messages. A related matter, which we felt really should be addressed was the lack of a FIX dictionary that included the messages specific to MTS BondsPro. Having to compile our own FIX dictionary was somewhat tedious, especially since the actual field order of the MTS BondsPro market data incremental refresh messages did not match the documentation.

These points aside, the API is clearly a major step forwards for the bond markets, bringing them a step closer in terms of automated trading to equities and FX. For market makers, the API represents a substantive efficiency opportunity, but it also opens the door to a whole new range of trading strategies, in terms of both time frequency and arbitrage.

  • Copyright © Automated Trader Ltd 2017 - Strategies | Compliance | Technology

click here to return to the top of the page