Nov
6

Formula 201 – #6 Local Variables and Recursion

I am going to discuss the use of Local Variables in formula indicators. I will also demonstrate the programming technique called recursion that can help resolve many problems related to indicator programming.

Local Variables

When we assign an expression to a variable with the $ prefix, we are creating a local variable. Here is an example.

$myavg := average (data1, 10)

Just like the series variables, you can use the value stored in the local variable anywhere within the formula. The only difference is that there is no BarsAgo parameter for the local variables. Each local variable store one and only one value at a time.

So what is the difference between the statement above, against the one below using series variable?

myavg2 := average (data1, 10)

The main difference is the cost of memory usage.

The series variable myavg2 has the ability to reference to its previous values (like myavg2 (1), myavg2 (2), etc. ), that implies NeoTicker has to store the previous values somewhere.

The local variable $myavg, however, cannot reference to its previous values. All it has is the value last assigned to the variable.

For most situation, you will not notice the difference, until, you are working with extremely long historical data series. For example, if you are charting 1-minute bar of some instrument over the past 10 years, you are working with 390 1-min bar per day, 260 trading days a year, for 10 years. Thats more than 1 million bars in total. If your formula indicator is using many series variables, the memory usage will add up quickly and if you are running low in memory, both Windows and NeoTicker will be affected.

If you use local variables for calculations that do not require the use of previously calculated values, you will then save all those memory for other important usage.

The second reason for using local variables is to improve performance. Using local variables are in general faster then using series variables due to their simple nature. Thus proper use of local variables improve the overall performance of your indicators.

Again, for most situations, you will not even notice the difference in performance due to the fact that the computers we use today is so much faster than the ones just a few years ago. More importantly, for most situation, you will not be working with that many bars per data series. Only trading system developers will face this problem everyday because backtesting inheritedly requires the use of as much data as possible.

Recursive Programming

Recursion is the concept of defining an item based on the item itself.

In formula, we can utilize this concept in both local variables and series variables.

For local variable, the idea is pretty clear. Here is an example.

$counter := $counter + 1

When an indicator instance is first initialized, all its local variables are set to zero. Thus, the above statement will keep increasing the local variable $counter by 1 whenever the indicator is updated.

For series variable, the idea is getting more complex, as we have a choice of which previous value to use. More precisely, its which previous bar value of the series variable we are going to use.

For example,

counter := counter (1) + 1

It is doing exact the same thing as the previous example with local variable.

But, if the definition looks like this,

counter := if (counter (1) = 0, 1, counter (1) + counter (2))

It can get very confusing, indeed.

The above formula returns the sequence of numbers 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

It is the famous Fibonnacci series.

(If you do not understand what the if function does, or, if you have not followed the exercise in the previous tutorial to read about decision functions, it is time you read Formula 101 #4 in details.)

So, what is the practical use of recursion in technical analysis?

In short, the ability to retain specific values for future reference.

For example, you want to use the previous day low as a reference price for the calculation of your special percentage change, then you can retain that price by using the following 2 statements,

mylow := if (date <> date (1), low, minList (low, mylow (1)));
myprevlow := if (date <> date (1), mylow (1), myprevlow (1))

The series variable myprevlow will contain the previous day low information that you want, you can then apply that in your calculation.

Due to the fact that we need to access the previous value of mylow in the definition of myprevlow, we cannot convert it to local variable. But, for the series variable myprevlow, it is referring to its own previous value only, which, by definition, can be handled by local variable.

Here is the local variable version,

mylow := if (date <> date (1), low, minList (low, mylow (1)));
$myprevlow := if (date <> date (1), mylow (1), $myprevlow)

Creating an Hourly Pivot Point Indicator

We will work on a real life indicator that plots the pivot lines based on hourly high, low, and close.

First, let me explain the basics of pivot points if you do not know what they are already.

Pivot points, are originally known as floor trader support/resistance levels. Floor traders (specifically, the ones from the S&P pit) like to use the previous trading day high, low, and close prices to compute a set of 5 price levels as the support/resistance price levels to work off.

The definition of each price level is as follows,

H2 = Avg + H1 - L1
H1 = Avg * 2 - Low
Avg = (High + Low + Close) / 3
L1 = Avg * 2 - High
L2 = Avg + L1 - H1

After these support/resistance formulas got publized, many variations of the formulas are introduced. And many novel ways of using the formulas are invented along the way.

What I am going to do, is to create an indicator that uses the high, low and close of the previous trading hour as the reference prices and plot the hourly pivots on the chart.

Here is the Indicator Specification.

formula201 part6 indicator spec

Notice there are 5 price levels that we are going to plot, thus we have to define the indicator with 5 plots. The visual tab has set the plots to use the plotting style of HLine and Dot. Just follow the screenshot and set your indicator exact like that. We will talk about the plotting styles after we have completed the indicator.

There are no parameters for this indicator.

Now, the script.

formula201 part6 script

If you are learning the formula language, do not be offended by the number of lines in the script. Just read the lines carefully, one line at a time. You will find that you can understand them.

The most tricky line is the first assignment statement because it is the key to controlling the rest of the formula so that it can properly collect high and low data every hour. You do not need to invent your own tricky formulas all the time. By reading and learning from examples like this one, you will build up your bag of tricks over time.

Another interesting thing is that I freely insert the comments within the first assigment statement. Remember that it is good practice to put comment your formula to explain to yourself why a particular statement is written the way it is. That will help you in the long run to properly maintain your indicators.

success1, success2, success3, etc. are predefined series variables. When you assign zero to these variables, it indicates to NeoTicker that the corresponding plot series is an invalid point and should not plot anything.

For example, if success1 is assigned to 0, then the current bar plot1, no matter what value is assigned to it, will have its state set to invalid. To set a plot series valid, assign non-zero value to the corresponding success series. If a particular success series is not defined in your formula indicator, it is assumed that you want to plot that particular series, meaning that the success series is default to true all the time.

After you install the indicator, you can test it out in your chart. Remember that this indicator is designed to work on intraday charts, thus you need to use intraday data to display the indicator properly.

Here is how it looks like.

formula201 part6 chart

We can now see how the HLine style and Dot style plot series look like.

HLine plotting style is designed for the display of horizontal lines. When there is a change of value to draw on the chart, it will automatically skip to the new price level and smartly not connecting that to the previous price level.

Dot plotting style is more general in its usage as it does not connect the dots together anyway. Thus it is useful for plotting price levels similar to the HLine style, and is more flexible when the price level changes frequently. For example, many users like to use dot style to display the parabolic indicator.

Summary

Using local variable is not hard. They just work like the series variables, with less options. The hard work lies in the process of properly identifying which part of your indicator can be implemented in local variables so that you can take advantage of their speedier performance and memory saving ability.

As I said many times, to learn formula writing, you have to actually start writing your own indicators. Just reading what I presented here will not make you an expert. It takes practices to acquire a skill. To acquire the skill of formula writing, start writing indicators today.

Complete Indicator

My Hourly Pivots.

(April 20, 2006 – indicator updated to take into account of the initial condition of the current_hour_low series variable)

Exercise

1. Create an indicator that plots a dot whenever the price bar trades through the high, the low, or the close of the previous trading day. For all other cases the indicator should draw nothing.

Answers For Previous Exercise

1. First we have to plan what we need in terms of parameters.

For the momentum indicator, it takes 1 integer parameter.
For the smoothing of the momentum indicator, it requires 1 integer parameter.
For the long term average and the standard deviation, it takes 1 integer parameter.
For the band, it takes 1 real parameter.

Thus our indicator will require 4 parameters in total.

Here is the formula,

plot1 := mo (data1, param1);
plot2 := average (plot1, param2);
plot3 := average (plot1, param3);

sd := stddev (plot1, param3);
plot4 := plot3 + sd * param4;
plot5 := plot3 - sd * param4

Discuss this article.

Leave a Comment

Blog Developed
By ContentRobot