Wednesday, December 26, 2007

Details . . .

As promised, this post aims to provide some background to what's happening in our first system.

Initially, we defined an indicator by calling:

Indicators["MA"].CreateIndicator(new SMA(20))

  1. Indicators["KEY"] is a property of the SystemBase class that returns an instance of the IndicatorManager Class. More precisely, it returns an object of type SymbolIndicatorCollection for which "KEY" is the key to a specific indicator instance held in the collection.
  2. CreateIndicator is a member method of this selection and takes an argument of type ISeries, which we supply by creating a new object SMA(int period).
My C# is a bit rusty but I think CreateIndicator actually expects any object that implements the ISeries interface, so not really an object (well, I guess an interface is also an object). Any C# buffs out there please advise what the correct interpretation is here.

The remaing commands set the inputs for our SMA to the open price and tell RE to show them on any charts the user calls up from the system.

  1. SetInputs is a member method of the SymbolIndicatorCollection it takes a generic 'object' as an input. This method is overriden for each Indicator, so that it deals with the parameters as necessary. Here we have used a member of the BarElement enumeration, which encompasses commonly used constants such as Open, High, Low, Close, Volume, etc.
  2. AddToCharts is also a member method of the SymbolIndicatorCollection but it does not require any further inputs.
Moving on to the NewSymbolBar function which is called for each new bar while running through the data for each symbol in a watch list, we first note that it takes two parameters:

  1. Symbol which is a class in the RightEdge.Common namespace and maintains information about the asset the symbol represents (Assetclass, Contract Type, etc). This may not be very interesting for stocks but could be very important for futures, options, etc. (think of roll-over dates, etc.)
  2. BarData which is also a class in the RightEdge.Common namespace and contains the information for the current day (for the current symbol). Typical information such as Open, High, Low and Closing price but also Volume and Open Interest are passed to your system through this variable.
The next thing we do in this function is to define local variables that represent the indicator and other data items we might use to figure out whether we're buying today or not.

  1. ISeries MA = Indicators["MA"][symbol] defines a variable MA of type ISeries (which is a basic object/interface defined in RightEdge.Common). As we have seen above, we use Indicators["MA"][symbol] to retrieve the moving average timeseries from the Indicator collection. The first part of the expression returns the collection of calculated indicator time series (SymbolIndicatorCollection); the second angular bracket returns the specifc calculate time series for the current symbol (and is of type ISeries).
  2. IList bars = Bars[symbol] defines a variable bars that is actually a list of BarData items (see above). It does this by using the Bars property of the SystemBase class (which returns an object of type list).
In particular this last nugget of information is crucial and took me a while to figure out by looking at some of the examples and some forum posts (again, the Developer's manual only lists the pieces, these posts are trying to show you how they fit together). You will likely need to refer to information about yesterdays, or last week's bars a lot and this is how you get the data into your system. In Wealth-Lab, this would be akin to functions like PriceOpen(), etc.

The if statement is then fairly straightforward - we access yesterday's moving average value by using the indexer [] provided by the ISeries object, which returns the value at a specified index from the start of the simulation period (i.e. ZERO to today, hence the use of the count property to return the index for today's value). Note that we are using yesterday's value: NewSymbolBar looks at today, so placing an order today, potentially for today's close on today's data would not be a good idea (looking ahead). We use two conditions to identify a crossover, based on closing prices.

Finally, we use the OpenPosition method of the SystemBase class to execute a buy order at today's open price for this symbol and bar. Notice that this function would also take a limit price and, where required, a number of shares.

That's it for tonight. Hope it helps and sheds some light.

Footnote: Some of the function calls are confusing because the go back to methods of the base class and it seems that some variables are conjured up out of thin air. For example the Indicators["MA"] call is really a this.Indicators[] call and access an object defined in the base class. If you're well versed in Object Oriented Programming then this is easy, but it helps me (semi-novice) in my thinking.

No comments: