As a trader-programmer you prefer to spend as much time as you can on the premise of your problem; less so the quirky logic optimization required to make your relatively simple indicator finish calculating some time this century. Optimizing your PRT indicator to make it run as quickly as machine-ly possible is something of a dark art – that is, at least if you’re used to a rock solid programming language like C, or like most others in fact!
Have you ever wondered if the bull market will be over by the time your backtest finishes? Or by the time your indicator loads on 200k candles? Let’s take a closer look at their interpreted “language” and find out what makes things go snappier….
In a normal programming language: If you had a bunch of conditions that you wanted to test for, say 10 or so, which all had to be true in order to proceed to the next part of the program, what would normally be the fastest way get a logical true or false? Would you create a variable for each sub-condition and then AND them all together? No! Of course you wouldn’t! Because that would waste unnecessary memory and time, to keep assigning conditions to a stack of variables in RAM; variables which you are never going to use again would be wasteful – you’d think. Do you see where I am going with this yet? 🙂
Let’s look at an example. Do you think this code would be
a) The fastest possible way to do this?
b) The slowest possible way to do this?
1 2 3 4 5 6 7 8 |
once x = 3 * pipsize once y = 2 * pipsize TMA8 = TriangularAverage[8](open) bc1 = low < TMA8 and close > open and open - low > close - open and high - close <= y and close - open >= x and close > TMA8 and open > TMA8 // bc1 = true | false |
You might be forgiven in thinking that the above would be fast. Why should it be fast? Because you aren’t wasting resources. You are assigning a bunch of unique conditions inline to a single variable stack (it’s a stack in PRT – bc1[x] for each candle). But like me if you thought that is fast in PRT, you would be very mistaken. It’s the slowest possible way to get the answer to bc1! Go figure! (using brackets around the conditions makes no difference).
Here is a (slightly) faster method:
1 2 3 4 5 6 7 8 |
TMA8 = TriangularAverage[8](open) ca1 = close > TMA8 and open > TMA8 and close > open ca2 = low < TMA8 ca3 = (open - low) > (close - open) ca4 = high - close <= 2 * pipsize ca5 = close - open >= 3 * pipsize bc1 = ca1 and ca2 and ca3 and ca4 and ca5 |
So, writing inefficient code; wasting resources by assigning a variable stack to a bunch of sub-conditions is faster. This by the way (above) was some original code I found on the site. So, can we make it even faster? Yes… we can. By this logic, the more you abstract the faster your program gets. But there comes a point where too much abstraction is unnecessary, resource hungry and pretty ugly!
Here is the fastest possible solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
TMA8 = TriangularAverage[8](open) x = 2 * pipsize y = 3 * pipsize oml = open - low cmo = close - open hmc = high - close cAo = close > open ca1 = close > TMA8 ca2 = low < TMA8 ca3 = oml > cmo ca4 = hmc <= x ca5 = cmo >= y ca6 = open > TMA8 bc1 = ca1 and ca2 and ca3 and ca4 and ca5 and ca6 and cAo // bc1 == true | false |
Now, is that ugly or is that ugly? The joys of an interpreted language. Nevertheless I hope this has given some insight into what you might want to consider if speed is an issue for your indicator or backtest.
All the best,
Maz
What about this way? Will it be faster?
If open – low then
If close – open then
If high – close then
If close > open then
If close > TMA8 then
If low cmo then
If hmc = y then
If open > TMA8 then
Endif
Endif
Endif
Endif
Endif
Nested “If…Then” loops as you are proposing are usually much slower than one single “If…Then” condition. The type of code you have written should normally be avoided for speed reasons. For another example, see the chapter “Limit nested loops” in the Prorealtime programming manual.
I assume this way of coding will help to speed up live trading execution as well?
Maz thanks for this post – your posts are always excellent. I guess beauty is in the eye of the interpreter but yes this would blow out how many lines I have for some systems in ProOrder.
The part I’m not sure about is this comment:
But there comes a point where too much abstraction is unnecessary, resource hungry and pretty ugly!
If more abstraction increases speed doesn’t this also mean it reduces resource use?
And how much faster was the final solution?