by July 16, 2023 in Free Trading System, Introduction, Python, TradingSimula-18, Trend Following System
onMany of TS-18 Indicators are Class Based and Here is Why!
Many indicators need their prior bar’s value to calculate the current bar’s value. In Python, external modules or functions that calculate these values have amnesia; they can’t even remember what their prior output was. In TS-18, all indicators and their associated classes and functions are inside the indicator.py module. Indicators, such as a simple moving average, do not need to know their prior values so this indicator is function based. This indicator can do all of its calculations with amnesia. An indicator such as Wilder’s Directional Movement has multiple output values such as ADX, ADXR, DMIPlus and DMIMinus. Many of these output values need the prior bar’s value to be calculated properly. Most of the calculations that need a memory are of the smoothing variety such as an exponential moving average or even a simple moving average. Since we can’t simply use a function, a class that can store all of the output from all the prior bars is needed. There’s that word “class” again. I have already programmed a bunch of indicators in TS-18 and Wilders Directional Movement is one of them. I am not going to bore you with the actually coding of the indicator, but I am going to show you how to use the indicator in trading system. I will partially pull the cover off the class by disclosing its instance variables. These variables contain similar information for each instantiation of the class but can contain different information. I just said a lot with that last sentence, so let us break it down. A class is basically a template and when you assign a new variable to a class, you are simply copying the template to that variable name – this is called instantiation. Take a look at the instance variables to the Wilders Directional Movement class template.
The word self and dot notation are the syntax that must be used when working with classes. Self just refers to itself – the template. All the instance variables except for two are lists. I made them list in case I need to use any of the variables prior values. Once I append information to these lists inside the class, I will always have access to each variables’ prior values. In other words, they have dimension or depth. Self.smooth is simply the smoothing factor, and it is scalar in type. Scalar just means it contains a single value, no depth or memory.
In a TS-18 module, you inform TS-18 that you will be using the ADX class by turning in on with True.
This code is located near the top of the code listing for the module. If useADX == True, then a list of ADX instantiations is generated by the for-loop. Why a list? Remember we need a class or template for each market in the portfolio. Each element in the list is a variable that refers to a different ADX class. Remember we leapfrog from one market to another on every day of data. When we leapfrog, we need to make sure we are looking at the corresponding class that is connected to correct market. Hence a list. Take a look at this code and I will go over it afterward.
In addition to instance variables, you also have class functions known as methods. Think of instance variables as nouns and methods as verbs. Inside the ADX class, I have a function called calcADX. This is a rather complicated function that calculates the following: ADX, ADXR, DMIPLUS, and DMIMINUS. This function/methods needs to be fed the following data to accomplish its task: high, low and close data for the current market, the length of the indicator, the current bar being evaluated in the portfolio and the offset. If I want to take action today, I need to know what the ADX values were as of yesterday’s close, so I offset the calculation by one day. Once the calculation takes place, the instance variables are filled in. Upon instantiation, the class or template is like a coloring book before it has been touched by a crayon. Once a class method, that acts upon the instance variables is invoked, the crayons get to work and fill in all the empty spaces. You gain access to these freshly calculated or colored variables by using dot notation. The class method is invoked as well with dot notation.
adxList[curMarket].calcADX(myHigh, myLow, myClose, adxLen, curBar,1)
Dot notation refers to the use of a “ . “ (period or dot) to dig into the class to call the proper method and access the proper instance variable. The curMarket index refers to the current market in the adxList being evaluated in the back test on the particular day. Now if you were just testing one market you could do this and not use a list.
Here I assign myADX to the adxClass() template and then use it to call the calcADX method and then use it to extract the instance variables that I need. In place of 14 as the adxLen in the first method call I use 20 in the second. Here is the printout when I print out dmiPlus, dmiPlus1, dmiMinus, dimMinus1, adx and adx1.
Since the instance variables are lists, you must access them using -1 or -2 to get the last and second to last elements. Take a look at these trade directives to see if they make sense to you. This strategy buys when the ADX is greater than 25 and DMIPLUS crosses above DMIMINUS. A $2000 stop is used as a money management stop. Notice how I test for the two indicators values crossing each other in the Long and Short Entries.
Thi