Zen and the art of ATS design...

Quote from TraderMojo:

Whilst I'm waiting for the inevitable flood of responses to the real-time topic I'll continue with where I left off on the SignalGenerator.

I realize it might be a little difficult to see the whole picture at the moment but hopefully things will become clearer once I draft the next UML for this part of the system.

In order to do that, I need to refine the list of order management methods that I want to make available to the system developer . So, I'm jumping back to that before I cover scripting:

1. Order Management methods

I've spent a little while thinking about this one and have gone around in circles a bit. Looking at Wealthlab for example, there is a bewildering array of order management or "trading system" functions: http://www.wealth-lab.com/cgi-bin/WealthLab.DLL/getpage?page=FnTradingSystem.htm

Neoticker has a similar range of functions.

Cursory analysis suggests that some of the proliferation is perhaps due to the lack of callback functions that Mojo Trader will have. The most important one is the onPositionOpened() handler. This method I envisage as being used to trigger stop loss or profit target orders.

If anyone has experience with other trading software e.g. Tradestation, Amibroker etc. and are familiar with their order management methods, please add your input here!

I'll start off with the basics and some design options.

Terminology

1) Method names could reflect: long or short
2) Method names could reflect: buy or sell
3) Method names could reflect: buyToOpen, buyToClose, sellToOpen, sellToClose.
4) Method names could reflect buy, sell, buyToCover, sellShort

So effectively, there are two issues there: whether to use Long/Short or Buy/Sell nomenclature and whether to differentiate between operations if there is already a position.

I have seen some software give their order management methods the following semantics:

Buy - will close existing short position and open a new long position.
Sell - will close existing long position and open a new short position.

In effect, the order will be double the size if there was an existing position in the opposite direction.

Order Types

It seems to be the norm to provide separate methods for the different order types e.g.:

buyMarket (or just buy)
buyLimit
buyStop
etc.

Ditto for Sell methods.

Annotations

It seems sensible and is widely practiced to have annotations or notes metadata for an order for logging purposes. How best to implement this? From an end user point of view, simply having two different methods seems the most obvious choice e.g.

buyMarket(arg1,arg2);
or
buyMarket(arg1,arg2,"Yabadabadoo!");

i.e. provide an overloaded method for each order management method there is. This doubles the number of methods which bothers me a little. I wonder if Java's varargs might be of use here? Thanks to dcraig for bringing that to my attention.

Position Size

It makes a lot of sense and again is not uncommon to separate out position sizing or money management e.g. http://www.geniustrader.org/

The question is how best to do this or rather at this point, how best to present the options to the end-user developer via the order managment methods.

The conclusion I have come to is to again offer two versions of the same method. One where the position size is explicitly specified and the other where it is not and thus deferred to the position size strategy to figure out e.g.

buyMarket(arg1,100,"I have explicitly set the position size of this order!);

or

buyMarket(arg1,"The position size strategy is going to figure out the size of this order for me!");

I'll leave the details of position sizing or money management to a later discussion as there are a few options for dealing with that.

What I think is important is that a reference to the order created is returned from all of these order management methods so that the SignalGenerator can keep a hold of them and interrogate their properties later on. So, however the position sizing is done as long as this requirement is met there shouldn't be a problem.

Specifying the Instrument for the Order

This is yet another issue that could result in the proliferation of methods.

Multi-instrument strategies are crucial for my purposes and I'm not convinced this issue is supported properly by some software though I see the latest RightEdge beta now seems to have support for this.

It seems as if Multi-instrument support was a bit of an after-thought for NeoTicker as all of the order management methods are replicated with "Ex" versions which allow the specification of the instrument.

The question is how best to deal with specifying which instrument to trade. There are various options:

1) If you want to trade the Instrument that is applicable to the current event e.g. onBar() then either the Instrument is specified in the handler e.g. onBar(Instrument i,Bar b) and there fore when it comes to order management you do:

buyMarket(i,100,"100% up room to go!");

2) Alternatively, the instrument applicable to the current event is set by the Strategy so all you have to do is:

buyMarket(100,"No fear!");

This mandates an extra method on the SignalGenerator interface: setCurrentInstrument(Instrument i) which gets called just before the event handler. I'm trying to think if there are possible synchronization issues with this approach.

3) However, if you want to trade a separate instrument which is distinct to those for which you are receiving market data then you can explicitly create the appropriate instrument (perhaps in a initialization method and saved to a member variable) and then reference that Instrument in the order method e.g.

buyMarket(myOtherInstrument,100,"Arb city!");

Conclusion

Your thoughts an opinions much appreciated! Ideally, I'd like to keep the order management methods as clean and simple as possible but it's difficult to see how the number can be kept down whilst at the same time keeping the burden on the programmer to a minimum in terms of remembering which arguments to specify.

To summarize the optionality of arguments we have:

1) Annotation/Note
2) Position Size
3) Instrument

And then different methods for each order type and direction combination.

Remember these order management methods are not only creating an Order object but they are also submitting them to the OrderManager or perhaps being passed through some filters before it reaches the OrderManager.

If you're still awake after reading this lengthy post then let me know any ideas you have.

Tricky business order management, I suspect. Other issues to consider:

1. Order routing where there is a choice of exchanges or even choice of brokers.

2. Time in force.

3. One cancel all order groups. On the assumption that your broker is likely to be an order of magnitude more reliable than an internet connected ATS, if positions are bracketed by a stop and a limit then a OCA order group is preferable to having the ATS cancel the other order when one is filled.

4. What is a reasonable common denominator of order functionality that the ATS should expect from a broker interface ? This might be a tough one to answer.

I agree that an order reference/annotation is absolutely essential.
 
Quote from Valdis:

Again, it's all here:

"Introduction to SmartQuant Strategy Development" guide

http://www.smartquant.com/introduction/smartquant_strategy.pdf

QuantDeveloper actually offers several models for ATS development:

Component (partitioned) model offers component based strategy design (Entry, Exit, MoneyManager, RiskManager, ExposureManager, ExecutionManager, etc.) + Signals that propagate from Entry through Money, Risk, Exposure and get converted to broker orders in the Execution Manager.

ATS (integrated) model offers one component responsible for Entry, Exit, Risk, Money and Exposure management logic and direct order routing.

There are also per instrument and cross market types of components. Per instrument components help to easily develop alpha strategies (trend following, gap, swing, directional, etc). Cross market components help when you want to trade correlations (static arbitrage, pair trading, correlation matrix, index replication, sectors, etc.)

There are more than 20 ATS strategies from "Trade Like a Hedge Fund" and "Beyond Technical Analysis" books discussed in details in this manual.

Enjoy and copypaste :D

Don't you think you have made your point by now ? Enough.
 
Quote from dcraig:

Tricky business order management, I suspect. Other issues to consider:

1. Order routing where there is a choice of exchanges or even choice of brokers.

Agree. Part of this goes back to the question of instrument normalization that I raised earlier on in the thread.

Essentially, the solution is to have an equivalent to Fatrat's Product Manager/ NeoTickers Symbol Manager.

What you do is set up an Instrument definition which contains information such as Symbol, Currency, Exchange perhaps. I was thinking of modelling the fields on IB's Contract object and/or the FIX Instrument block.

Then, you have mappings that are able to translate that Symbol to Provider specific Symbols and definitions if neccessary.

It is the job of the provider adapter to look up the mapping from the Instrument registry when it is passed the normalized Instrument object/Symbol.

So for IB you would specify SMART or the specific exchange you wanted to use for that Instrument. Of course, this means there is only the choice of using one exchange per symbol and it is basically set at design time.

So a strategy which needed to trade the same symbol but at different exchanges would only be supported by first retrieving the Instrument from the Instrument Registry (or unless it was was set or passed in to the method) and then explicitly set the exchange before passing it to the order management method thus:

Code:
onBar(Instrument i, Bar b) {

i.setExchange("SMART");
buyMarket(i,100,"Smart routing please");

}

As for dealing with choices of brokers, that's an interesting one. I must admit I only considered the scenario where a Strategy would only use a single broker for execution (as defined in the configuration file). In the Strategy's startup/initialization, it connects to the specified market data provider and broker.

I suppose some sophisticated ATS would want to execute via multiple brokers and/or accounts from the same strategy? If you could provide a use case for this, that would be great.

Of course, the current architecture already facilitates different strategies using different brokers.


2. Time in force.

Yes, I missed that one. Yet another optional argument. I'm going to have a look at varargs in more detail.


3. One cancel all order groups. On the assumption that your broker is likely to be an order of magnitude more reliable than an internet connected ATS, if positions are bracketed by a stop and a limit then a OCA order group is preferable to having the ATS cancel the other order when one is filled.

Agree. Utilizing the broker's OCA mechanism is preferable where possible. I was looking at how creating an OCA group and submitting it could be made easy from an API level. The simplest solution is to have yet another optional argument which specified the OCA group identifier for separate orders.

As stated earlier the buyMarket,buyLimit methods are essentially convenience methods that not only create Order objects but also submit them to the OrderManager (or to Order Filters before getting to the OrderManager).

There's no reason to dissallow the end-user from creating Order objects manually and submitting them to the OrderManager themselves e.g.

Code:
myOCAGroup = new OCAGroup();
myOCAGroup.addOrder(new Order(OrderType.STOP,xxx,"Stop Loss"));
myOCAGroup.addOrder(new Order(OrderType.LIMIT,xxx,"Profit Target"));

//we have direct access to the OrderManager through the
//construction of the base class
orderManager.submitOCAGroup(myOCAGroup);

What do you think? The OCAGroup object deals with assigning the group identifier to the Order objects it is composed of.


4. What is a reasonable common denominator of order functionality that the ATS should expect from a broker interface ? This might be a tough one to answer.

Agree, I have no idea what is reasonable in this respect until I have a look at some other broker interfaces. The suggestion you made earlier about capabilities interrogation of the provider interface seems to be one way to deal with it.

As for broker's that don't support OCA natively, the functionality could possibly be built into the OrderManager so when OCA groups are submitted to it, it first finds out if it is supported by the broker (via interrogation), if not, it maintains the responsibility for the OCA group, cancelling the respective order at the correct time which it should be able to do with little effort as it receives execution reports.
 
Quote from dcraig:

Don't you think you have made your point by now ? Enough.

I was going to ask for a free copy of his software since he kept referring me to it.

Seems all of his posts have now been removed.
 
As far as optimization goes, using reflection doesn't seem like a good idea to me. Why not set the values for the optimization parameters in the XML file that is passed in to create a strategy? This will be also useful to allow the user to manually tweak those values.

Instead of having a bunch of overloads to your submit order function, I would recommend just having one function, and passing an Order object to the function. A lot of the members of that object could be optional. If you want to make things easier for strategy developers, you could have a wrapper around the broker interface that provided different functions such as BuyLimit(), BuyAtMarket(), etc. That way each broker wouldn't have to implement all those different methods.
 
Quote from dsplaisted:

As far as optimization goes, using reflection doesn't seem like a good idea to me. Why not set the values for the optimization parameters in the XML file that is passed in to create a strategy? This will be also useful to allow the user to manually tweak those values.

Certainly, it was the intention to provide ability to specify user parameters for a strategy in the XML configuration file. However, I was differentiating between ordinary user parameters and parameters that could be optimized. Perhaps there is no need to differentiate here and put the optimization parameters along with their ranges/values in the configuration file too. If I were to do that, it would impact on how I planned to go about doing the optimization runs so I need to think about it.


Instead of having a bunch of overloads to your submit order function, I would recommend just having one function, and passing an Order object to the function. A lot of the members of that object could be optional. If you want to make things easier for strategy developers, you could have a wrapper around the broker interface that provided different functions such as BuyLimit(), BuyAtMarket(), etc. That way each broker wouldn't have to implement all those different methods.

I probably wasn't clear. The next UML diagram should clear things up though.

The buyMarket(),buyLimit() functions are just convenience methods that live only in the SignalGenerator class/interface being overriden. In the background they construct an Order object and submit it to the OrderManager (possibly via filters,position sizing)

Essentially, they are only there to provide some sort of resemblence to other software and to make the developer's life just a little bit easier and strategy logic easier to read. They are very thin wrappers consisting of one or two lines of code.

There is nothing to stop the developer manually creating Order objects and submitting them to the OrderManager directly as illustrated in the OCAGroup example a couple of posts ago.

The broker only has one execution method as per the Provider interface.

Thanks for the feedback! Any more insight welcome.
 
Here is a simplified sequence diagram that I hope will shed some light on the situation.

It illustrates the sequence of messages that might occur when a trade event happens and your strategy logic wants place a market order inside an onTrade() handler e.g.

Code:
onTrade(...) {
   //...trade decision logic goes here.
   buyMarket(...);
}

simpleendtoendsequenceti2.jpg


When broken down like this, it is hopefully starting to look quite straightforward.

SimpleMarketDataHandler is simply an implementation of IMarketDataHandler. IBProviderAdapter is an implementation of IBroker and IMarketDataProvider as per the Provider subsystem discussed earlier.

I have used a fictional EventDispatcher in this sequence diagram to keep things simple for the moment in lieu of JMS/Spring Events/JMX Notifications etc.

In .NET you would probably use Events and Delegates etc. if you were happy with things all being in the same process and slightly tighter coupling. I'm not really familiar with those technologies though so I'm not sure of any shortcomings they might have with respect to concurrency and poorly behaved listeners.

I may or may not employ a separate OrderFactory later on and submission to the OrderManager might be delegated back the the enclosing Strategy rather than directly from the SignalGenerator so that filters can be applied . These are all things that will be refined but the basic idea remains as above in the diagram.
 
Back
Top