Something seems definitely wrong in your Indicator:
- Your loops don't go over the available data and are instead "stuck" in time! Since, you set all arrays to NOT as "Series", you are constantly referring to the "oldest" bars available, never current ones.
- Also, yet again you are mixing Old Style way with New Style. Since you are using the "OnCalculate()" event, you must use the parameters "rates_total" and "prev_calculated". Do not use "IndicatorCounted()".
- Another, problem is that you start using the array contents with "ArrayMaximum()" and "ArrayMinimum()" but you never initialise the contents of those arrays on the first call to the event.
As a reference to help you out, take a look at the "Heiken Ashi" indicator provided by MetaTrader. I've attached here just for easier access but it should be in your Indicator's folder.
False. You can use rates_total and prev_calculated, you don't have to. You can use IndicatorCounted in OnCalculate just fine. Ignore the arguments, use the Predefined Variables, all the Timeseries and Indicators Access functions (e.g. iBarShift, iCustom,) and leave the buffers defaulted to series and count down to zero (current bar.) You can use rates_total and prev_calculated, set everything to non-series and count up. . | int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]){ int counted_bars=IndicatorCounted(); int shift=Bars-1-MathMax(Length, counted_bars); if(counted_bars == 0){ ... } for(; shift>=0; --shift){ int iHL = iHighest(NULL,0, MODE_LOW, Length, shift); |
False. You can use rates_total and prev_calculated, you don't have to. You can use IndicatorCounted in OnCalculate just fine. Ignore the arguments, use the Predefined Variables, all the Timeseries and Indicators Access functions (e.g. iBarShift, iCustom,) and leave the buffers defaulted to series and count down to zero (current bar.) You can use rates_total and prev_calculated, set everything to non-series and count up. |
Given that MQL5 does not use "IndicatorCounted()" and that it follows the "OnCalculate()" style, what you saying may be true but is VERY BAD ADVICE especially taking into account the near future merging of Metatrader 4 and 5.
Hi guys, thanks for both of your imput.
Fernando, the indicator you have attached is actually the "template" for the code I've posted. I've made a few adjustments to the code in order to make it easier to read but you'll notice that the arrays are set as NOT as series in there, too (i've just continued using that format as i assumed as it's a stock indicator it would be ok to carry on in doing so).
Are there any articles relating to the merger of MQL4 and 5? I was of the understanding that they were going to remain separate due to the different functionality of MT4 and 5 - although i can't find the article where i think i read that, so could quite easily be mistaken and have taken it out of context!
As an experiment (and it'll be good practice, too) i'll re-code my indicator counting down and see if that makes any kind of difference.
Bwalya, I was originally using iLowest/Highest but as I'm counting in the direction i am it was getting a bit confusing - iLowest/Highest count and start parameters got a bit awkward to use; ArrayMax/Min use the index positions which of course match the way in which i count (due to the arrays being NOT as series).
***Edit: I believe the arrays need to be set as series as the first candle on a Heiken Ashi chart is always a standard (OHLC) candle and any subsequent candle is then a HA candle.
Hi guys, thanks for both of your imput.
Fernando, the indicator you have attached is actually the "template" for the code I've posted. I've made a few adjustments to the code in order to make it easier to read but you'll notice that the arrays are set as NOT as series in there, too (i've just continued using that format as i assumed as it's a stock indicator it would be ok to carry on in doing so).
Are there any articles relating to the merger of MQL4 and 5? I was of the understanding that they were going to remain separate due to the different functionality of MT4 and 5 - although i can't find the article where i think i read that, so could quite easily be mistaken and have taken it out of context!
As an experiment (and it'll be good practice, too) i'll re-code my indicator counting down and see if that makes any kind of difference.
Bwalya, I was originally using iLowest/Highest but as I'm counting in the direction i am it was getting a bit confusing - iLowest/Highest count and start parameters got a bit awkward to use; ArrayMax/Min use the index positions which of course match the way in which i count (due to the arrays being NOT as series).
***Edit: I believe the arrays need to be set as series as the first candle on a Heiken Ashi chart is always a standard (OHLC) candle and any subsequent candle is then a HA candle.
The problem is not the "setting as NOT as series". The problem is that your loops are "static"! They must "roll" (for lack of a better term), just like in the original "Heiken Ashi" indicator!
PS! Yes, MT4 and MT5 may remain separate, but surely you can see that they are more and more similar by the day. Sooner or later, MT4 will die off (or be killed), so the sooner you adapt to the new style MQL5 way, the better your code will adapt for the future.
Are you referring to my loop stating: for(i=4; i<=4; i++) ? When i'm not intentionally going through the chart 1 bar at a time it states: for(i=4; i<=Lookback; i++) - Lookback=IndicatorCounted. When the latter is stated then my chart is fully populated with HA candles. Perhaps i misunderstand what it is you mean. Sorry, this is my first attempt at coding.
Are you referring to my loop stating: for(i=4; i<=4; i++) ? When i'm not intentionally going through the chart 1 bar at a time it states: for(i=4; i<=Lookback; i++) - Lookback=IndicatorCounted. Perhaps i misunderstand?
But why repeat the process on every call to "OnCalculate()". It should just pick-up from the previous calculations. That is what the parameter "prev_calculated" is for. Contrary to what WHRoeder has stated, I don't agree with him, because "rates_total" and "prev_calculated" works differently to "IndicatorCounted", and for someone like yourself that has still not understood the mechanism, it just confuses and messes everything up.
Also why use a loop for "for(i=0; i<1; i++)" for just one index and then execute that on every single call to "OnCalculate()".
Besides the Heiken Ash Indicator, take a look at some of the others that use the OnCalculate() and compare them to find the similarities and differences, so that you can understand the concept.
PS! If you want, send me a PM with your "real" code, and I will look it over and make changes to it for you based on what you require. Just send me the details of what you want coded.
Fernando, that's an extremely kind offer, however, i really need to get to grips with this if i stand any chance of being able to properly understand it/fix any issue in the future. Also, a whole heap of things have just clicked for me off the back of your last 2 comments; I didn't realise i was going through every bar on the chart on each call to OnCalculate and now see the relevance prev_calculated. I've just had a look at the CCI indicator code and i see exactly what it is your refering to. I'm going to modify my code and retest. If i'm still having the same problems after implementing your recommendations i'll update this thread/PM you.
Thanks again. :)
First define your maximum lookback. | int lookback = ... // iMA(period) has look back of period. // buffer[i+2] has look back of 2 (as TimeSeries) // buffer[i-2] has look back of 2 (not TimeSeries) // use maximum of all. int lookback = ... // iMA(period) has look back of period. // buffer[i+2] has look back of 2 (as TimeSeries) // buffer[i-2] has look back of 2 (not TimeSeries) // use maximum of all. |
Old way, counting down as a TimeSeries | int counted = IndicatorCounted(); for(int iBar = Bars - 1 - MathMax(lookback, counted); iBar >= 0; --iBar){ // Timeseries and Indicators Access uses index=iBar } |
New way, counting down as a TimeSeries (Bars always equals rates_total so can be substituted.) | for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar){ // Timeseries and Indicators Access uses index=iBar https://docs.mql4.com/series } return rates_total-1; // Recalculate current bar next tick. Returning rates_total-1 makes prev_calculated the same as IndicatorCounted(). Alternatively if you return rates_total then must decrement
prev_calculated if non-zero at the beginning of On_Calculate to recalculate
the current bar. Always count down so you're not using future values. |
New way, counting up, not a TimeSeries. | set all accessed arrays and buffers to ArraySetAsSeries(false) Not the Predefined Variables for(int iBar = MathMax(lookback, prev_calculated; iBar < Bars; ++iBar){ // To access a Timeseries use index=Bars -1- iBar // and convert any results back index=Bars -1- result } return rates_total-1; // Recalculate current bar next tick.Always count up so you're not using future values. |
New way, counting down as a TimeSeries, but not through bar zero. | #define LAST 1 for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= LAST; --iBar){ : } return rates_total-MathMax(1,LAST); // Recalculate Bar LAST once on new bar. |
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Goodmorning all.
I'm trying to create a "dynamic" range using ArrayMax/Min - as each new bar comes in (and assuming some other criteria are met) the range extends in length - to achieve this I have elected to create a variable, the value of which changes upon each new candle (and some other criteria), and placed this into the count parameter in place of a fixed value. My ArrayMin range appears to be working OK but not the ArrayMax, even though both functions are pulling their data from the same source.
Just so we're all on the same page:
1. My array index positions and "ï" match - 0 is the oldest bar on the chart.
2. My terminal options are set to have a Max of 5000 candles in the history and 5000 on the chart; as i'm printing my own candles i turn off the built in bars/candles.
3. I've been testing this on a bar by bar basis - by manually incrementing expression2 (starting with candle 4 - so you'll need to scroll all the way to the left) of the for loop on a weekly EUR/USD chart and have left the attached code in this state so you can see for yourselves - should you need to look. I've highlighted the for loop in question.
Assuming your set-up matches that which i have stated above you should see the following:
1. [0] is the "last" (in this case also the first) swing point.
2. [1] is the highest candle on the chart.
3. [3] is the lowest candle on the chart.
4. i=[4].
5. The number of bars in either range is 4 (derived by the calculation: int Bars_In_Range=i-Last_Swing).
6. The range Low is [3].
7. The range High is [5] where i'm expecting it to be [1] - This is particularly confusing to me as [5] hasn't even been printed on the chart yet.
8. If you manually enter 4 into the ArrayMax "count" parameter then the range does what i'm expecting it to and reports [1] as the range high.
Apologies if that's a little long winded i just wanted to make sure i gave you the correct info.
Here's the code:
As always, thanks to anyone that can advise what it is i'm doing wrong.
Thanks,
Carl.