Zen and the art of ATS design...

Discussion in 'Automated Trading' started by TraderMojo, Nov 29, 2006.

  1. As I alluded to in the previous post, the Strategy configuration may end up being quite complex. It is quite possible that it will be one of the largest classes in the framework. As such, I expect to re-visit the class definition for Strategy multiple times to iterate and refine.

    Here are some elements that I see being part of the strategy configuration:

    Basic Parts

    1) A reference to the Signal Generator class for the strategy. This is the class that will contain the core decision making processing for the strategy. It's responisbility is to generate buy/sell signals.

    2) A reference to the market data provider to use for this strategy.

    3) A reference to the broker to use for this strategy.


    These are the absolute fundamental pieces of information that make up a strategy configuration. There are a lot more that I will be discussing later but I'd like to concentrate on these pieces first to nail down some design decisions.
     
    #61     Dec 8, 2006
  2. Okay, so far so good.

    Let's walk through this basic Strategy class:

    It has a static factory method getInstance() which is responsible for creating a fully configured Strategy object/instance.

    A mock XML file e.g. :
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <mojo-strategy xmlns="..." ...>
      <name>FooStrategy</name>
      <market-data-provider>OpenTick</market-data-provider>
      <broker>IB</broker>
      <signal-generator>org.mojotrader.MySignalGenerator</signal-generator>
    </mojo-strategy>
    
    Hopefully that is self-explanatory. Even with just a few entities, I have simplified the contents shown. Any XML experts out there, care to comment on schema design style e.g. attribute-based vs element-based xml.

    So, the getInstance() factory method is responsible for taking the XML given it (or file) and constructing an appropriate Strategy object. Simple enough. Later on, as the Strategy configuration grows the construction will become more complex...and believe me there is a lot more to come.

    Now we have a Strategy object with the following members:

    - name
    - marketDataProvider
    - broker
    - signalGenerator

    These are presumably set through the constructor. The only one there with a need for an accessor method is name - getName(). This name will be used by the StrategyContainer as a key to the Strategy list (Hashtable) and also perhaps for display purposes.

    Other methods on the Strategy object as was seen in the sequence diagram:

    - play()
    - stop()

    Even with this extrememely simplified arrangement some design issues become apparent if we walk through the sequence of events:

    1) StrategyContainer (or other) calls play() on Strategy.
    2) Strategy gains access to the market data provider and broker and calls connect() on them (as per IProvider interface)
    3) Strategy then calls subscribe() on the market data provider (as per Provider interface) to start receiving relevant market data events.

    The first issue is from 2): how does the Strategy get access to the providers? It implies there needs to be some kind of Provider Registry which is persistent. Each provider can be registered in the registry using a unique name e.g. IB, OpenTick as per getName() on the IProvider interface. getName() must therefore be a static/class method.

    The problem is, what if I want to connect to IB with two different configurations (different ports). Two different strategies running at the same time with two different IB configurations....

    The second issue is from 3): how best to define how the strategy knows which market data to subscribe to? Options are:

    1) Declaratively specify the symbols in the XML configuration file.
    2) Programatically specify the symbols as part of the strategy - using a separate class to return a symbol list.

    I like the first approach because it allows the XML file to be modified by end-users of a black-box system.

    The second approach is perhaps more appropriate when the symbol list is potentially large or complicated to construct declaritively e.g. Option Series. Though, there could be declaritive shortcuts for this in XML.

    Thoughts/opinions people?
     
    #62     Dec 8, 2006
  3. Is it wise to allow a live and test strategy to be running in the same container?
     
    #63     Dec 8, 2006
  4. Good question. The answer is: it's probably not wise at all. However, what I had in mind is a situation where you could run a strategy in "live mode" but it is actually executing against a paper trading account at the broker and is operating in real-time. For example, Interactive Brokers have a paper trading account facility. It is a kind of "live test". This perhaps explains my obsession with needing multiple settings for the same Broker Provider.

    To be clear, this is different to a plain "test" mode for mass backtesting where you are executing against a local dummy broker with configurable fill quality/slippage, commission settings etc. in faster than real-time (unless otherwise configured for real-time playback)

    That really is the only reason I'd want to support the running of live and test strategies at the same time because of my specific requirements. It might not actually be applicable to anyone else.

    I'd prefer to avoid the introduction of a third or more modes.

    There is of course nothing to stop you from loading multiple containers in separate VMs though to remove single point of failure for all strategies. However, when you do this it makes it difficult to have rules that span all strategies such as limiting the max drawdown for a day.

    Your comments welcome.
     
    #64     Dec 8, 2006
  5. Good answer. I suppose for ultimate peace of mind a live strategy could run in its own container, hosted on seperate hardware altogether.
     
    #65     Dec 9, 2006
  6. Zooming out for a moment to look at the bigger picture, here is a higher level overview.

    The system is based on the following premise:

    "Any strategy decision making logic needs to either be notified of information or be able to interrogate for information to the same level of detail (or greater) that a human decision maker would be able to."

    With that basic premise in mind, I'm refining a list of system events that need to be propogated to the strategy in addition to defining interfaces for the strategy to access information on demand.

    The following is a general diagram that might help non-techies and techies alike comprehend on some level, the general concept of the system and it's composition:

    [​IMG]
     
    #66     Dec 12, 2006
  7. I havn't read your doc, but I'm not sure that position manager == portfolio manager. Portfolio is probably best considered as a collection of systems. Each system and possibly an associated position manager could very well manage multiple instruments. You can then do interesting things at the portfolio level llike optimization.
     
    #67     Dec 13, 2006
  8. Yes, I think that is the way I see it.

    There is a one-to-one mapping between Strategy and Position Manager. The Position Manager manages the positions for a Strategy. Strategies can be multi-instrument and therefore there can be positions for more than one Instrument in the Position Manager.

    As far as Portfolios are concerned, I'm still considering how best to approach the issues of Portfolio level backtesting and optimization. I understand the lack of Portfolio backtesting is an issue with Tradestation.

    Any further ideas on the Portfolio idea is much appreciated.
     
    #68     Dec 13, 2006
  9. OK, back to the Strategy class and associated issues.

    To recap: Strategy is configured and instantiated based on an XML configuration file. The configuration has information specifying details such as market data source and broker to use. Crucially, it also specifies a SignalGenerator class to use for the strategy.

    I'd like to now discuss the SignalGenerator here in more detail. (Suggestions for alternative naming is welcome - I might rename Strategy to StrategyController and SignalGenerator to Strategy or something...).

    In brief, the SignalGenerator is the main class for coding strategy logic. It is the place where most trading decisions are made. It is the place that effectively acts as a substitute for your brain: it receives all (almost) information your brain would receive and makes trading decisions.

    It is the trading system ChartScript in Wealthlab. It is the Trading System formula in Neoticker. It is the SystemMain class in RightEdge etc.

    Given it is the core class that any system developers will be working with, the interface is quite important.

    The main areas that need to be considered are:

    1) Order Management methods.
    2) Event handlers.
    3) Access to OrderManager and PositionManager.
    4) Optimization.
    5) Scripting Support.
     
    #69     Dec 13, 2006
  10. I'll start out of sequence with the Event Handlers.

    2. Event Handlers

    These are the hooks that get invoked when certain events happen in the system. The developer of a strategy can use these hooks to make trading decisions.

    As per my earlier post, it would be nice if the strategy was notified of all the events a human would be.

    At this point I envisage the Strategy to have a generic handleEvent() method to pick up events from the event bus (the implementation of which is still to be decided). The Strategy then looks at the event and calls a more easily understood event handler on the SignalGenerator

    There is one handler method per event type. Here is the list of event handler methods I have come up with so far:

    Market Data related handlers:

    onBar() - this is the standard event handler seen in most software.
    onQuote()
    onTrade()
    onMarketDepth()

    Order Manager related handlers:

    onOrderFilled()
    onOrderCancelled()

    Position Manager related handlers:

    onPositionOpened()
    onPositionClosed()

    Optionally, Provider related handlers:

    onConnected()
    onDisconnected()
    onError()
    onMessage()

    If you think I have missed any pertinent events please let me know.

    These methods would obviously form part of an interface ISignalGenerator but to remove the burden on having to implement all of the methods, a "noop" implementation would be provided e.g. SignalGeneratorSupport. This is the actual class that would need to be overridden for strategy development.
     
    #70     Dec 13, 2006