You may have seen many examples of formula language already, but still have little or no idea of how to construct your own indicator or trading system. This tutorial offers a number of case studies that illustrate the basic capabilities of the Trademan formula language and some of the things you can do with it. Let's start off with something very simple and work our way along to more interesting and perhaps challenging applications. To follow along with the examples, bring up your copy of Trademan, select the Money Flow Index indicator and click the "Define" button in the lower left of the Control Panel under the indicator list.Daily Range
Daily range is simply the difference between the high and the low prices for the day. An indicator showing Daily Range will plot this value as a series of points joined by a line. Each point represents the value of the Daily Range on the date for which the point is plotted. Let's define the new indicator.
Write the formula
Look at the upper left corner of the dialog first. The name of the new indicator appears in the edit area of the corner combo box. I typed it in, and you will have to, also. Since we want to look at the output of this indicator, click the "Enabled" checkbox so that it has a checkmark in it. Next, we enter the formula in the topmost edit box. Note that there is a list box just above this edit box that shows the words "Primary Indicator" selected. We are entering the formula for the primary line for this indicator. You can also enter secondary and tertiary indicators, but we'll get to that later. To enter the formula you can either type it in or select from the lists at the top of the dialog. In this very simple example, we can get everything from the two rightmost boxes.
Set up the display
Next, since we want to display this indicator, we need to enter some display instructions to tell Trademan how to plot the data. In this case, all we need are a label for the legend, which I entered as "DR" in the Primary Label box and a label for the indicator axis, which I entered as "Daily Range" in the Axis Label box. The second item also appears in the title for the plot. Next, select the "Auto Scale" radio button in the Scaling section at the bottom to tell Trademan to calculate the vertical axis from the range of data it receives. You will want to use this option when you have an indicator whose range of values is not obvious or predefined. As the last step in the definition of this indicator, go to the top of the page and click the "Define" button. This action writes the new formula definition to disk. If you don't do this before you leave the definition dialog or before you look at another definition in the dialog, your definition will be lost. Make it a habit to click the "Define" button as you proceed. To proceed to the next section, exit the definition dialog by clicking the Cancel button or the upper right hand X button in the window. This brings us back to the Control Panel.Examine the Results
If you followed instructions and clicked "Define" when you finished your definition, you should find a "Daily Range" item in the Indicator list box. To find it quickly, just type in the first few letters, i.e., "dai," then select it from the list. Next, click the Plot button. That will cause a plot window to pop up with the display for the first stock in the portfolio you have currently selected. For this plot I have selected the sample portfolio and also the "Large Plot" option at the bottom of the window. Note that the daily readout appears below the plot area. Here I am reading out "DR," which is the Daily Range. To switch from price readout to indicator readout, hold down the Shift key on your keyboard and click the left mouse key. The DR for 24 July 2002 is 2.31. When I switch back to price readout (Shift+click again), I see high = 24.61 and low = 22.30. Looks like it worked!
Averaged Daily Range Bands
The Daily Range indicator as it stands now is pretty jagged and maybe not terribly useful. Let's smooth it and see what happens. In fact, let's make a band system out of it. That way, we'll have a simple indicator that tells us if the price is tending outside its typical daily range.Enter a function
To get this going, the first thing we want to do is calculate a moving average of the daily range. Trademan provides a set of mathematical functions that perform operations like this that are useful for technical analysis. You will find the moving average by selecting "mvg avg" from the second list box from the left. When you select the mvg avg item you will see the line of text above the list box change. This text tells you the proper "syntax" for the moving average function. The syntax of an expression is its textual form. In the case of the moving average, you type "mov(" followed by an expression for the data to be averaged, a comma, an expression for the period over which you want to average, and a closing parenthesis. You can get an explanation of this function by hitting F1 on your keyboard. Now, you can type in "mov(" just before "high-low" or you can move the cursor in front of "high-low" and double click "mvg avg" in the list. Either action produces the following display. In this case, we see that "high-low" takes the place of the "data" entry (or more mathematically, the data argument) for mov.
Parameterize the Indicator
To finish up the formula definition, we need to add an expression for the "period" argument of mov and then add the result to the average of the closing price. This will provide the line plotted for the upper band of our system. Type a comma after "high-low" and go over to the "Input Data" list box. If you scroll down a little way, you will find entries for "parameter 1," and so forth. Click on "parameter 1" and observe that "parm1" appears in your formula after the comma. Type a closing parenthesis after this and we're done with the averaged daily range.What have we just done here? A parameter represents a constant value passed to a function for a particular calculation. You can alter the value of a parameter, but its value stays fixed for the duration of the calculation you call its function for. Your formula definitions take on different roles depending on whether they define a top level indicator that is called directly from the Control Panel or whether they serve as part of an expression in some other formula definition. Right now, we are defining an indicator to be called from the Control Panel, but we will revisit using an indicator as part of an expression a little further along. In specifying "parm1" in a top-level indicator definition, we put a place holder for the first parameter passed from the control panel. This is the entry that occupies the upper right hand edit box on the Control Panel. It can be integer or floating point, but it must be a constant number. In the case of the averaged Daily Range, this parameter will pass on the number of data points that we want to use in computing the average daily range.
Finish the First Formula
Now we want to finish the first formula by adding the averaged daily range to the average of the closing price. How to start should be pretty clear by now. Type in a plus ("+") sign and then "mov(." You can put in white space if you like, but not between "mov" and "(." The data argument of this second mov function can be found in the "Input Data" list box as "close." Click on this entry to put into your formula, then type in a comma to separate it from the next argument. This can be a fixed number of your choosing, parm1 if you want the averaging on the bands and the closing price to be the same, or parm2 if you want to control both averaging parameters from the Control Panel. I'm going to type in the last option, so we'll have a doubly-parameterized indicator.
Write the Second Formula
At this point, I want to click the "Define" Button, just to make sure everything so far is saved. Oooops!
What happened is that the dialog checked for errors before saving the definition. We specified that we want to display this indicator when we checked the "Enabled" box. This means not only that we can plot the indicator but that we can use it in screens, as well. The screen dialog needs to know what indicator parameters are enabled, and we have to let it know somehow. The way Trademan chooses to communicate this information is by Parameter Labels. The parameter label gives a hint to the user as to the meaning of a parameter. It tells Trademan that a parameter is needed by the indicator. If you need a parameter for your indicator and don't give it a label, it can cause the screener to crash because the indicator doesn't have the right parameters to calculate with. OK, let's type some parameter labels in and get on with it. I'll just put "Band Avg" into the "Parameter 1 Label" box and "Price Avg" into the "Parameter 2 Label" box.
Now let's enter the second formula. We know that the second formula will be about like the first, except that we will subtract the averaged daily range from the averaged price. Let's steal the first formula by copying it to the clipboard. If you don't know how to do this, just select the whole formula and hit ctrl-C on your keyboard. Go up to the little list box above the top formula entry box where "Primary Indicator" is now selected. Click the lower arrow to the right of the list box to expose "Secondary Indicator" and select it. Move to the formula entry box and paste by hitting ctrl-V on your keyboard. Cut (ctrl-X) and paste (ctrl-V) until you have the expression for the price average minus the daily range average. Click the Define button.
Set up for Plot
Our original definition of Daily Range has changed, so we need new legend labels. I just put "Band +" into "Primary Label" and "Band-" into "Secondary Label." The entry in "Axis Label" changed to "Daily Range Bands." Now we need to put default values into the parameter definitions. I chose 5 for the Band Avg and 14 for the Price Avg. Once we set the Scaling option we're done. Since the bands express a price range plotted around the price, let's use the "Price Scale" option. Click the Define button, and we're done.
Buy and Sell Signals
If we look at the new band indicator plotted with some price data, we might notice that short term price trends are often predicted by the closing price moving outside one band or the other. That is, if the price is below the lower band and moves above it, we often get a strong upward swing in the price over the next several days. Conversely, if the price is above the upper band and moves below it, we often get a strong downward price trend. I don't want to get too hung up on this particular indicator, which is pretty primitive and lame, but let's use it to illustrate how you can develop buy and sell signals.Develop and Enter the Sell Signal
We want to signal a sell when the closing price crosses from higher than the upper band to lower than the upper band. We can use the ncross function for this, but there's a quirk in Trademan's interpretation of the buy signal that allows us to use a conceptually simpler expression. Signals are generally written so as to produce a true (expressed as 1) or false (expressed as -1) value. Trademan always places the signal at the crossover from negative to positive. Thus, we could just specify the condition of closing price being less than the upper band as our sell signal and get sell signals in the right place.
Let's use the two parameter form of Daily Range. Our sell signal is then "close < Daily Range(parm1, parm2)." Enter it into the Sell Signal Formula box, hit the Define button, and exit the definition dialog. Looking at the results of a plot, make sure you have the signals turned on. You can see that the sell signals occur when the close is lower than the upper band one day after it closed higher than the upper band. Yes, there are too many signals and most of them aren't too good. This signal plainly needs some work, but let's take care of that later.Using the new Indicator
How do we express the value of the upper band? There are at least two ways. The most obvious way is to retype the upper band formula: mov(close, parm2) + mov(high-low, parm1). Another way is to use the new indicator: Daily Range(parm1, parm2, 0, 0). We can use one or more parts of the Daily Range indicator in the definition of other parts as long as the new definition isn't contained in any of the parts it includes. We also can't refer to the part that we are defining as part of its own definition.
Default Parameters
In the indicator expression preceding we use Daily Range in its long form. An indicator requires four parameters but will use the default values for its parameters if you leave some off the end. Note that if you specify a value for a parameter, all parameters the precede it in the argument list must be specified. The default value for the fourth parameter, which specifies the indicator line to use, is 0, since we want use the upper band, which is the primary indicator. Since Daily Range requires only two parameters we could have typed "Daily Range(parm1, parm2)", "Daily Range(parm1)," or just "Daily Range," depending on how many parameters we are willing to default.Develop and Enter the Sell Signal
By now, you should see immediately that the buy signal is: "close > Daily Range(parm1, parm2)." Right? Not quite, because this compares the close to the upper band. The lower band is our secondary indicator, which is expressed as
"Daily Range(parm1, parm2, 0, 1)." Remember, that we have to use the non-default value in the last argument, so all the arguments must be filled in. Enter the formula into the Buy Signal Formula box, hit the Define button and exit the definition dialog. This time when we look at the plot results we have both buy and sell signals.
Improve the signals
It's pretty clear at this point that we have a lot of false signals to winnow out. Let's try coupling the Daily Range bands with an overbought/oversold oscillator such as Relative Strength index. If the Relative Strength Index is less than 30 an oversold condition is indicated, and if it's over 70 an overbought condition is indicated. Let's go ahead and try a straightforward implementation. Note that we switch to pcross and ncross instead of simple inequality expressions when we logically combine one signal with another. Otherwise, we would get a buy signal whenever close is greater than the lower band and the other signal fired. The behavior of the sell signal would be similar. The operator for a logical AND is "&&," as is the case in the C and C++ languages, as well as perl and java. Both arguments for this operator evaluate to true (1) or false (-1), as will the result.
Looking over the entire sample portfolio, I see one sell signal; and it's not a very good one. What's happening here? Clearly the Relative Strength Index is unlikely to be less than 30 when the price is rising strongly enough to recover past the lower band. It also seems that the Relative Strength Index is unlikely to be greater than 70 when the price is falling strongly enough to penetrate the upper band. Let's try something else. What if the Relative Strength Index had penetrated one of the thresholds in the right direction within the past few days? That would indicate recovery from an overbought or oversold and thus an imminent trend reversal, which is what our basic indicator is trying to detect. Here's what the implementation would look like.
We introduce the "since" function here. This function tests whether the condition expressed by the first argument has been true within the past number of days expressed in the second argument. Looking at the results we see some pretty good signals but also an unfortunate tendency to buy repeatedly during a long-term decline and to sell repeatedly during a long-term rise. Changing Price Avg to 21 produces better results, but maybe it's time to move on to more sophisticated indicators.