Just a very quick video to give you an idea on how easy it is to get up and running. This is a Bollinger Band Script that is included in Trend Following Systems: A DIY Project – Batteries Included
All posts by George Pruitt
Get My Latest Book-TrendFollowing Systems: A DIY Project – Batteries Included
Just wanted to let you know that my latest book has just been published.
Trend Following Systems: A DIY Project – Batteries Included: Can You Reboot and Fix Yesterday’s Algorithms to Work with Today’s Markets?
Trend Following Systems: A DIY Project – Batteries Included
This book introduces my new Python back-tester, TradingSimula-18. It is completely and I mean completely self contained. All you need is the latest version of Python and you will be up and running trading systems in less than 5 minutes. Fifteen years of data on 30 futures is included (data from Quandl). I have included more than 20 scripts that you can test and build on. This back-tester is different than the one I published in the Ultimate Algorithmic Trading System Toolbox. It utilizes what I call the horizontal portfolio spanning paradigm. Instead of sequentially testing different markets in a portfoio:
It process data in the following manner:
This form of testing allows for decisions to be made on a portfolio basis at the end of any historic bar. Things like inputting portfolio performance into an allocation formula is super simple. However, this paradigm opens up a lot of different “what-if” scenarios.
- What If I Limit 2 Markets Per Sector
- What If I Turn Off A Certain Sector
- What If I Liquidate The Largest OTE loser
- What If I Liquidate The Largest OTE winner
- What If I Only Trade The Ten Markets With The Highest ADX Values
All the data and market performance and portfolio performance is right at your fingertips. Your testing is only limited by your creativity.
The best part is you get to learn raw Python without having to install complicated libraries like SciKit, Numpy or Pandas. You don’t even need to install distributions of commercial products – like Anaconda. Don’t get me wrong I think Anaconda is awesome but many times it is overkill. If you want to do machine learning then that is the way to go. If you want to test simple Trend Following algorithms and make portfolio level decisions you don’t need a data science application.
There isn’t a complicated interface to learn. Its all command line driven from Python’s IDLE. 90% of the source code is revealed for the back-testing software. Its like one of those see-thru calculators. You see all the circuits and semiconductors, but in Python. So you will need to flow through the code to get to the sections that pertain to your test. Here is a small sample of how you set up the testing parameters for a Donchian Script.
Everything is batched processed: set up, pick market or portfolio, run. Then examine all of the reports. Here is an example of the sector analysis report.
Plus I include EasyLanguage for the majority of the scripts. Of course without the portfolio level management. I am working on a new website that will support the new book at TrendFollowingSystems.com.
Please take a look at my latest book – it would make an awesome Christmas present.
Testing Keith Fitschen’s Bar Scoring with Pattern Smasher
Keith’s Book
Thanks to MJ for planting the seed for this post. If you were one of the lucky ones to get Keith’s “Building Reliable Trading Systems – Tradable Strategies that Perform as They Backtest and Meet Your Risk-Reward Goals” book by John Wiley 2013 at the list price of $75 count yourself lucky. The book sells for a multiple of that on Amazon.com. Is there anything earth shattering in the book you might ask? I wouldn’t necessarily say that, but there are some very well thought out and researched topics that most traders would find of interest.
Bar Scoring
In his book Keith discusses the concept of bar-scoring. In Keith’s words, “Bar-scoring is an objective way to classify an instrument’s movement potential every bar. The two parts of the bar-scoring are the criterion and the resultant profit X days hence.” Keith provides several bar scoring techniques, but I highlight just one.
Keith broke these patterns down into the relationship of the close to the open, and close in the upper half of the range; close greater than the open and close in the lower half of the range. He extended the total number of types to 8 by adding the relationship of the close of the bar to yesterdays bar.
The PatternSmasher code can run through a binary representation
for each pattern and test holding the position for an optimizable number of days. It can also check for long and short positions. The original Pattern Smasher code used a for-loop to create patterns that were then compared to the real life facsimile. In this code it was easier to just manually define the patterns and assign them the binary string.
Please check my code for any errors. Here I go through the 8 different relationships and assign them to a Patter String. “-+++” represents pattern number (7 ) or type (7 + 1 = 8 – my strings start out at 0). You can then optimize the test pattern and if the test pattern matches the actual pattern, then the Pattern Smasher takes the trade on the opening of the next bar and holds it for the number of days you specify. You an also designate long and short positions in the code. Here I optimized the 8 patterns going long and short and holding from 1-4 days.
Here is the equity curve! Remember these are Hypothetical Results with $0 commission/slippage and historic performance is not necessarily indicative of future results. Educational purposes only! This is tested on ES.D
Play around with the code and let me know if you find any errors or any improvements.
How To Program A Ratcheting Stop in EasyLanguage
When you program something like this you never know what is the best profit trigger or the best profit retention value. So, you should program this as a function of these two values. Here is the code.
So, basically I set my multiples to zero on the first bar of the trading session. If the multiple = 0 and you get into a long position, then your initial stop will be entryPrice + (0 – 1) * trailAmt. In other words your stop will be trailAmt (6 in this case) below entryPrce. Once price exceeds or meets 7 points above entry price, you increment the multiple (now 1.) So, you stop becomes entryPrice + (1-1) * trailAmt – which equals a break even stop. This logic will always move the first stop to break even. Assume the market moves 2 multiples into profit (14 points), what would your stop be then?
stop = entryPrice + (2 – 1) * 6 or entryPrice + 6 points.
See how it ratchets. Now you can optimized the profit trigger and profit retention values. Since I am keying of entryPrice your first trailing stop move will be a break-even stop.
This isn’t a strategy but it could very easily be turned into one.
Question on Multiple Time Indicator [Discrete Bars]
A reader of this blog proffered an excellent question on this indicator. I hope this post answers his question and I am always open to any input that might improve my coding!
Because I use BarNumber in my MODULUS calculation the different time frames that I keep track of may not align with the time frames on the chart; your 10-minute bar O, H, L, and C values may not align with the values I am storing in my 10-minute bar container. Take a look at this snapshot of a spreadsheet.
Here I print out a 5-minute bar of the ES.D. Because I use BarNumber in my Modulus calculation, I don’t get to a zero remainder until 9:50 in the 10, 15, and 20 minute time frames. At 9:50 I start building fresh 10, 15, 20 minute bars by resetting the O, H, L and C to those of the 5-minute bars. From there I keep track of the highest highs and lowest lows by extracting the data from the 5-minute bar. I always set the close of the different time frames to the current 5-minute bar’s close. Once the modulus for the different time frames reaches zero I close out the bar and start fresh again. The 25-minute bar didn’t reach zero until the 10:05 bar.
I will see if I can come up with some code that will sync with the data on the chart.
Passing a Two Dimensional Array to a Function- EasyLanguage
In this post, I want to share some code that I was surprised wasn’t really all that accessible. I was in need of passing a 2-D array to a function and couldn’t remember the exact syntax. The semantics of the problem is pretty straightforward.
- Build Array
- Pass Array as Reference
- Unpack Array
- Do Calculation
A 2D Array Is Just Like a Table
Any readers please correct me if I am wrong here, but you can’t use dynamic arrays on any dimension greater than 1. A dynamic array is one where you don’t initially know the size of the array so you leave it blank and TradeStation allocates memory dynamically. Also, there are a plethora of built-in functions that only work with dynamic arrays. Once we step up in dimension then that all goes out the window. I know what you are thinking, just use multiple dynamic arrays. Sometimes you want to keep the accounting down to a minimum and a matrix or table fits this bill. So if you do use multi-dimension arrays just remember you will need to know the total number of rows and columns in your table. Table? What do you mean table? I thought we were talking about arrays. Well, we are and a two-dimensional array can look like a table with rows as your first index and columns as your second. Just like an Excel spreadsheet. First, let’s create a very small and simple table in EasyLangauge:
My EasyLanguage Sandbox
You will notice I used the keyword Once. I use this whenever I want to play around with some code in my EasyLanguage Sandbox. Huh? In programmer-ese a Sandbox is a quick and dirty environment that runs very quickly and requires nearly zero overhead. So here I apply the code to print out just one line of output when applied to any chart. Notice how I declare the 2-D array – use the keyword Array: and the name of the array or table and allocate the total number of rows as the first argument and the total number of columns as the second argument. Also notice the arguments are separated by a comma and enclosed in square brackets. The following value enclosed in parentheses is the default value of every element in the array. Remember arrays are zero-based in EasyLanguage. So if you dimension an array with the number 2 you access the rows with 0 and 1 and 2. Same goes for columns as well. Did you catch that. If you dimension an array with the number 2 shouldn’t there be just 2 rows? Well in EasyLanguage when you dimension an array you get a free element at row 0 and column 0. In EasyLanguage you can just ignore row 0 and column 0 if you like. Here is the code if you ignore row 0 and column 0.
Should I Use Row 0 and Column Zero – It’s A Preference
Out Of Bounds
Even though you get one free row you still cannot go beyond the boundaries of the array size. If I were to say something like:
testArray[3,1] = 300;
I would get an error message. If you want to work with a zero element then all of your code must coincide with that. If not, then your code shouldn’t try to access row 0 or column 0. Okay here is the function that I programmed for this little test:
Notice in the inputs how I declare the tempArray with the values x and y. You could have used a and b if you like or any other letters. This informs the compiler to expect a 2D array. It doesn’t know the size and that’s not important as long as you control the boundaries from the calling routine. The second parameter is the number of rows in the table and the third parameter is the column I am interested in. In this example, I am interested in column 2.
The Caller Function is the QuarterBack – Make Sure You Don’t Throw it Out of Bounds
Again this function assumes the caller will prevent stepping out of bounds. I loop the number of rows in the table and examine the second column and keep track of the highest value. I then return the highest column value.
This was a simple post, but remembering the syntax can be tough and know that EasyLangauge is zero-based when it comes to arrays is nice to know. You can also use this format for your own Sandbox.
MULTI-TIME FRAME – KEEPING TRACK OF DISCRETE TIME FRAMES
Just a quick post here. I was asked how to keep track of the opening price for each time frame from our original Multi-Time Frame indicator and I was answering the question when I thought about modifying the indicator. This version keeps track of each discrete time frame. The original simply looked back a multiple of the base chart to gather the highest highs and lowest lows and then would do a simple calculation to determine the trend. So let’s say its 1430 on a five-minute bar and you are looking back at time frame 2. All I did was get the highest high and lowest low two bars back and stored that information as the high and low of time frame 2. Time frame 3 simply looked back three bars to gather that information. However if you tried to compare these values to a 10-minute or 15-minute chart they would not match.
In this version, I use the modulus function to determine the demarcation of each time frame. If I hit the border of the time frame I reset the open, high, low and carry that value over until I hit the next demarcation. All the while collecting the highest highs and lowest lows. In this model, I am working my way from left to right instead of right to left. And in doing so each time frame is discrete.
Let me know which version you like best.
Using a Dictionary to Create a Trading System
Dictionary Recap
Last month’s post on using the elcollections dictionary was a little thin so I wanted to elaborate on it and also develop a trading system around the best patterns that are stored in the dictionary. The concept of the dictionary exists in most programming languages and almost all the time uses the (key)–>value model. Just like a regular dictionary a word or a key has a unique definition or value. In the last post, we stored the cumulative 3-day rate of return in keys that looked like “+ + – –” or “+ – – +“. We will build off this and create a trading system that finds the best pattern historically based on average return. Since its rather difficult to store serial data in a Dictionary I chose to use Wilder’s smoothing average function.
Ideally, I Would Have Liked to Use a Nested Dictionary
Initially, I played around with the idea of the pattern key pointing to another dictionary that contained not only the cumulative return but also the frequency that each pattern hit up. A dictionary is designed to have unique key–> to one value paradigm. Remember the keys are strings. I wanted to have unique key–> to multiple values. And you can do this but it’s rather complicated. If someone wants to do this and share, that would be great. AndroidMarvin has written an excellent manual on OOEL and it can be found on the TradeStation forums.
Ended Up Using A Dictionary With 2*Keys Plus an Array
So I didn’t want to take the time to figure out the nested dictionary approach or a vector of dictionaries – it gets deep quick. So following the dictionary paradigm I came up with the idea that words have synonyms and those definitions are related to the original word. So in addition to having keys like “+ + – -” or “- – + -” I added keys like “0”, “1” or “15”. For every + or – key string there exists a parallel key like “0” or “15”. Here is what it looks like:
– – – – | = | “0” |
– – – + | = | “1” |
– – + – | = | “2” |
You can probably see the pattern here. Every “+” represents a 1 and every “0” represent 0 in a binary-based numbering system. In the + or – key I store the last value of Wilders average and in the numeric string equivalent, I store the frequency of the pattern.
Converting String Keys to Numbers [Back and Forth]
To use this pattern mapping I had to be able to convert the “++–” to a number and then to a string. I used the numeric string representation as a dictionary key and the number as an index into an array that store the pattern frequency. Here is the method I used for this conversion. Remember a method is just a function local to the analysis technique it is written.
This is a simple method that parses the string from left to right and if there is a “+” it is raised to the power(2,idx) where idx is the location of “+” in the string. So “+ + – – ” turns out to be 8 + 4 + 0 + 0 or 12.
Once I retrieve the number I used it to index into my array and increment the frequency count by one. And then store the frequency count in the correct slot in the dictionary.
Calculating Wilder’s Average Return and Storing in Dictionary
Once I have stored an instance of each pattern [16] and the frequency of each pattern[16] I calculate the average return of each pattern and store that in the dictionary as well.
When you extract a value from a collection you must us an identifier to expresses its data type or you will get an error message : patternDict[patternString] holds a double value {a real number} as well as patternDict[patternStringNum] – so I have to use the keyword asType. Once I do my calculation I ram the new value right back into the dictionary in the exact same slot. If the pattern string is not in the dictionary (first time), then the Else statement inserts the initial three-day rate of return.
Sort Through All of The Patterns and Find the Best!
The values in a dictionary are stored in alphabetic order and the string patterns are arranged in the first 16 keys. So I loop through those first sixteen keys and extract the highest return value as the “best pattern.”
If Today’s Pattern Matches the Best Then Take the Trade
If today matches the best pattern then buy and cover after the second day.
Conclusion
I didn’t know if this code was worth proffering up but I decided to posit it because it contained a plethora of programming concepts: dictionary, method, string manipulation, and array. I am sure there is a much better way to write this code but at least this gets the point across.
Contents of Dictionary at End of Run
Example of Trades

Code in Universum
Using A Dictionary to Store Chart Patterns in EasyLanguage
Dictionary – Another Cool Collection Object
The dictionary object in EasyLanguage works just like a real dictionary. It stores values that referenced by a key. In a real-life dictionary, the keys would be words and the values would be the definitions of those words.
An Introduction
This little bit of code just barely skims the surface of the dictionary object, but it gives enough to get a nice introduction to such a powerful tool. I am piggybacking off of my Pattern Smasher code here, so you might recognize some of it.
Object Delcaration
Like any of the objects in EasyLanguage a dictionary must be declared initially.
Here I tell the editor that I am going to be using the elsystem.collections and then a declare/define a dictionary named patterDict and two vectors: index and values. In the Once block, I create instances of the three objects. This is boilerplate stuff for object instantiation.
The keys that index into the dictionary are strings. In this very simple example, I want to examine all of the different combinations of the last four-bar closing prices. Once the pattern hits up I want to accumulate the percentage change over the past three days and store that value in the location pointed to by the patternString key.
Notice how I displace the loop by three days (5-2 insteat of 3-0)? I do this so I can compare the close at the end of the pattern with today’s close, hence gathering the percentage change. Also, notice that I test to make sure there is an entry in the dictionary with the specific key string. If there wasn’t already an entry with the key and I tried to reference the value I would get an error message – “unable to cast null object.”
Once I store the keys and values I can regurgitate the entire dictionary very simply. The keys and values are stored as vectors. I can simply assign these components of the dictionary to the two vectors I instantiated earlier.
And then I can simply index into the vectors to print out their contents. I will add some more commentary on this post a little later this week. I hope you find this useful. And remember this will not work with MultiCharts.
Multi-Time Frame – Using Built-in Indicators and Multi Data Charts
A reader of this blog wanted to be able to use different time frames and some built-in indicators and output the information in a similar fashion as I did in the original MTF post. There are numerous ways to program this but the two easiest are to use data structures such as arrays or vectors or use TradeStation’s own multi data inputs. The more complicated of the two would be to use arrays and stay compliant with Multicharts. Or in that same vein use vectors and not stay compliant with Multicharts. I chose, for this post, the down and dirty yet compliant method. [NOTE HERE! When I started this post I didn’t realize it was going to take the turn I ended up with. Read thoroughly before playing around with the code to see that it is what you are really, really looking for.] I created a multi data chart with five-time frames: 5,10,15,30 and 60 minutes. I then hid data2 thru data5. I created an MTF indicator that plots the relationship of the five time frames applied to the ADX indicator with length 14. If the ADX > 20 then the plot will be green else it will be red. If all plots align, then the composite plot will reflect the alignment color.

This code is very similar to the original MTF indicator, but here I simply pass a pointer to the different time frames to the ADX function. Since the ADX function only requires a length input I had assumed I could use the following format to get the result for each individual time frame:
adxData1 = adx(14) of data1;
adxData2 = adx(14) of data2;
This assumption worked out.
But are we really getting what we really, really want? I might be putting too much thought into this but of the five-time frame indicator dots, only the 5-minute will change on a 5-minute basis. The 10-min dot will stay the same for two 5-min bars. The dots will reflect the closing of the PRIOR time frame and the current 5-min bar is ignored in the calculation. This may be what you want, I will leave that up to you. Here is an illustration of the delay in the different time frames.
So when you look at each dot color remember to say to yourself – this is the result of the prior respective time frame’s closing price. You can say to yourself, “Okay this is the ADX of the current 5-minute bar and this is the ADX of the prior 10-minute close and this is the ADX of the prior 15 minutes close and so on and so on. We all know that the last 5 minutes will change all of the time frames closing tick, but it may or may not change the price extremes of those larger time frames. I will show you how to do this in the next post. If you want to see the impact of the last 5- minutes, then you must build your bars internally and dynamically.