stevehopwoodforex.com
https://www.stevehopwoodforex.com/phpBB3/
Print view

MA of an indicator
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=1244
Page 1 of 1
Author:  Dewey McG [ Tue Nov 27, 2012 9:09 pm ]
Post subject:  MA of an indicator

This is very easy to do on a chart: just drag the MA onto the indicator (e.g. RSI etc.) and apply to Previous Indicator's data.

How do I write this in MQL? I want one of the conditions to be whether the MA is above or below the RSI.

Thanks
Author:  SteveHopwood [ Tue Nov 27, 2012 9:20 pm ]
Post subject:  Re: MA of an indicator

Dewey McG wrote:This is very easy to do on a chart: just drag the MA onto the indicator (e.g. RSI etc.) and apply to Previous Indicator's data.

How do I write this in MQL? I want one of the conditions to be whether the MA is above or below the RSI.

Thanks
I had to do something like this, although I cannot remember when, why or with what indicator. I do recall having to hand code the ma, by adding all the candle-close indi values together and dividing by the number of candles in the calculation.

I would love to know if others have better solutions, because this will arise again.

:D
Author:  ewinner [ Tue Nov 27, 2012 9:45 pm ]
Post subject:  Re: MA of an indicator

Hi Guys,

I have attached a couple of MA indicators i have used before in EA's

The iCustom code i was using is

double rsi = iCustom(Symbol(),0,"ema of rsi",89,34,0,0); //rsi value
double rsima = iCustom(Symbol(),0,"ema of rsi",89,34,1,0); //ma value

double cci = iCustom(Symbol(),0,"ema of cci",25,20,0,0); //cci value
double ccima = iCustom(Symbol(),0,"ema of cci",25,20,1,0); //ma value

Hope this helps
Mark
Author:  garyfritz [ Tue Nov 27, 2012 10:10 pm ]
Post subject:  Re: MA of an indicator

You can refer to things like the MACD indicator to see how they do it. Note though, the Empty4 examples all seem to be "simple answers for simple problems" and they never explain that it ONLY works for simple problems. E.g. MACD uses iMAOnArray() to calculate the MA of a buffer array and write it into another buffer array. That's the simple case. Non-buffer-array to buffer array, or non-buffer-array to non-buffer-array, are (I think!?) non-simple problems. Buffers have reverse order, where element 0 is the newest, and bars get shifted as new bars arrive. Arrays don't do that.

You can look at the AllAverages indicator to see an example of how it can be done with non-buffer arrays, but that code is incredibly obtuse and IMHO poorly written.
Author:  Dewey McG [ Tue Nov 27, 2012 11:04 pm ]
Post subject:  Re: MA of an indicator

ewinner wrote:Hi Guys,

I have attached a couple of MA indicators i have used before in EA's

The iCustom code i was using is

double rsi = iCustom(Symbol(),0,"ema of rsi",89,34,0,0); //rsi value
double rsima = iCustom(Symbol(),0,"ema of rsi",89,34,1,0); //ma value

double cci = iCustom(Symbol(),0,"ema of cci",25,20,0,0); //cci value
double ccima = iCustom(Symbol(),0,"ema of cci",25,20,1,0); //ma value

Hope this helps
Mark
Thanks.


Does method refer to what type of MA, Smoothed, Simple Exponential, etc.? If so, do you know which method applies to which number?
Author:  ewinner [ Tue Nov 27, 2012 11:41 pm ]
Post subject:  Re: MA of an indicator

Yes, set the method in the indicator itself

0 - Simple moving average,
1 - Exponential moving average,
2 - Smoothed moving average,
3 - Linear weighted moving average.

The iCustom code above gets 2 values from the indicator, put it on a chart and open your data window, you'll see RSI and Value 2 (MA Value). Using those values you can test higher or lower in your trading logic.

Mark
Author:  gaheitman [ Wed Nov 28, 2012 9:28 am ]
Post subject:  Re: MA of an indicator

garyfritz wrote:You can refer to things like the MACD indicator to see how they do it. Note though, the Empty4 examples all seem to be "simple answers for simple problems" and they never explain that it ONLY works for simple problems. E.g. MACD uses iMAOnArray() to calculate the MA of a buffer array and write it into another buffer array. That's the simple case. Non-buffer-array to buffer array, or non-buffer-array to non-buffer-array, are (I think!?) non-simple problems. Buffers have reverse order, where element 0 is the newest, and bars get shifted as new bars arrive. Arrays don't do that.

You can look at the AllAverages indicator to see an example of how it can be done with non-buffer arrays, but that code is incredibly obtuse and IMHO poorly written.
I did a little research in iMAOnArray() and I think I may have finally gotten some insight.

The Setup

Create two arrays of size 10 and fill them with the numbers 0, 10, 20 , 30 ...
Set one of them to be a series array using ArraySetAsSeries()

The test

Calculate a simple moving average of period 3 for each position of the array and store it in a result array. Do this three ways, once with the order of the loop from 0-9, once with the order 9-0 and once randomly.

The results

Code: Select all

Random Test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
80 70 60 50 40 30 20 10  0  0
Series Array
10 20 30 40 50 60 70 80  0  0

0-9 Test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
80 70 60 50 40 30 20 10  0  0
Series Array
10 20 30 40 50 60 70 80  0  0

9-0 test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
80 70 60 50 40 30 20 10  0  0
Series Array
10 20 30 40 50 60 70 80  0  0
The good news is, the order of iterating through the array to call iMaOnArray() does not matter.

Looking at the result, I'm willing to say that iMaOnArray() is working on the array as though it is a series array even if it isn't. That means when you ask for the zeroth element it is going to calculate the value by starting at the logically right-most element.

Huh?

In a normal array, we visualize the block of data holding the array as moving from left to right, with the leftmost element being the smallest index and the rightmost being the largest.

Code: Select all

[a][b][c][d][e][f][g][h][i][j]
In a series array, we flip the number line so that the order is reversed.

Code: Select all

[j][i][h][g][f][e][d][c][b][a]
I believe that iMaOnArray() doesn't care about the order, it is going to assume it is working with a series array, and when you ask for the zeroth element, it is going to give you the rightmost element. It calculates this element by looking at the data in the elements to the left of the index you ask for.

So, with the normal array when I ask it to calculate the zeroth element, it gives me the average of elements g, h, and i, even though I consider those elements 6, 7 and 8.

My advice is to always switch it to a series array or load the data in the array in reverse order. Switching to a series array seems easier.

I've attached the script I used for the test.

George
Author:  garyfritz [ Thu Nov 29, 2012 4:16 am ]
Post subject:  Re: MA of an indicator

Wow. Excellent sleuthing work, George!

I assumed iMAOnArray() worked in any order because you used MODE_SMA. The SMA is fully calculated for any bar in isolation, so you can calculate it in any order.

I expected different results for MODE_EMA, but:

Code: Select all

Random Test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
 80.02 70.04 60.08 50.16 40.31 30.63 21.25 12.5 5 0
Series Array
 9.98 19.96 29.92 39.84 49.69 59.38 68.75 77.5 85 90

0-9 Test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
 80.02 70.04 60.08 50.16 40.31 30.63 21.25 12.5 5 0
Series Array
 9.98 19.96 29.92 39.84 49.69 59.38 68.75 77.5 85 90

9-0 test
Data
 0 10 20 30 40 50 60 70 80 90
Normal Array
 80.02 70.04 60.08 50.16 40.31 30.63 21.25 12.5 5 0
Series Array
 9.98 19.96 29.92 39.84 49.69 59.38 68.75 77.5 85 90
MODE_EMA has to be calculated in oldest-to-newest order, so I expected it to work differently when you jumbled the order. To my surprise the order (random, 0-9, 9-0) DOESN'T affect the results.

So that must mean that it calculates the MA of the entire array the first time you call it, and stashes it away for later reference? And then it has to juggle it when new bars come in??

Series vs. normal still DOES affect the results, because as with MODE_SMA it's reversed the order of the array. Or reversed the order that iMAOnArray() accesses the array. I'm not sure which...

I thought iMAOnArray() on a normal array would work left-to-right, lowest-to-highest index. So MA(3) on elements 0 and 1 wouldn't work, and MA(3) on element 2 would give you the average of elements 0, 1, and 2. But I think you're right: iMAOnArray() works on a normal array as if it's a series array. In your example, getting the MA of element 0 on a normal array returns the average of elements 7, 8, and 9. So it acts as if the right-most highest-index element of the array is element 0.

Oy, my head. Rather than switching to series arrays and trying to keep this straight, it might be a lot easier and less trouble-prone to just forget about iMAOnArray() and write your averages yourself!!!!
All times are UTC Page 1 of 1