MT4 iMAOnArray and iBandsOnArray effect of number of elements on calculations - page 3

 
Alexey Viktorov:

No, Vladimir. It is a bit wrong.

In this case, you should apply ArraySetAsSeries(array, false); to an array of three hundred elements among which iMAOnArray() is considered. But we'd better use CopyOpen() instead of the array's filling loop.

As I understand it, in this variant it will be better to

The way the task was set, that's how I demonstrated it. It turned out very well. And then you yourself :)
 
Alexey Viktorov:

No, Vladimir. It is a bit wrong.

In this case, you should apply ArraySetAsSeries(array, false); to an array of three hundred elements among which iMAOnArray() is considered. But we'd better use CopyOpen() instead of the array's filling loop.

As I understand it, in this variant it will be better to

So show me the "working" variant of the code, the source code of the original is here, you are trying to cut it down to 12 elements instead of the requested three hundred, and it should eventually result in 3 indicator buffers with the specified data for displaying at least 300 elements in the basement, And then, when a new bar comes, respectively, 301 and then the value will be drawn, but do not forget that in this case, if you use 0 as a limit for the calculation, only the new bar will be recalculated, and the type of average (smoothing) for the second buffer is not necessarily SMA, and can be any of the 4 available.
 
Sergey Efimenko:

This is the question. If I don't need to calculate the whole array, but only the last N elements.

I don't quite understand the logic of calculating these functions when limiting. I have a timeseries array (one of the indicator buffers), if I leave the number of elements equal to 0, no questions, everything is counted and calculated, but if I decrease the number of elements involved in the calculation by the same shifts, I get only the primary ones. Simply speaking there is an array 5000 elements (bars on the chart), to save time I need to calculate only last 300, but when I specified the value 300 in the second parameter I got primary 5000-4700 elements, but on offset 300-0, and further values at a call don't change. What is the point of using this parameter?

The hell knows. Just forget about it. If you need to speed up calculations, reduce the number of items being calculated in your loop.

if(prev_calculated==0)limit=300; else ...; 

One of two things: either it is impossible or you need some secret combination of timeseries, not timeseries, calculation directions.

 
Dmitry Fedoseev:

Fuck knows. Just forget it. If you want to speed up the calculations, reduce the number of elements to be calculated in your cycle.

One of two things: either it's impossible or you need some secret combination of timeseries, not timeseries, calculation direction.

Yes, as I already wrote a bit earlier, there is only one possibility - to use your own analogues of the above functions, which can be used to calculate at least one element.

The paradox of the situation is that if we make a similar template, overlaying the average or bollinger bars on any indicator (price line), there will be no such slows down the initial calculation of all history bars, like when using these functions in the code, when restarting the terminal or switching the TF, so it is unclear, what takes so long to be calculated in these functions.

 
Dmitry Fedoseev:

Fuck knows. Just forget it. If you want to speed up the calculations, reduce the number of elements to be calculated in your cycle.

One of two things: either it is impossible or you need some secret combination of timeseries, not timeseries, calculation directions.

Also I used such a construction.

if (limit > 300)limit=300;

By the way,"MovingAverages.mqh" is twice as fast as"iMAOnArray", even the old version.

https://www.mql5.com/ru/forum/79988

Использование MovingAverages.mqh в MQL4
Использование MovingAverages.mqh в MQL4
  • www.mql5.com
При вызове в советнике индикатор работает корректно, но если его поместить в тело условного оператора "if", то советник не открывает сделок, хотя логика советника остается та же.
 
Sergey Efimenko:

Yes, as I wrote a little earlier, there is only one option - to use our own analogues of the mentioned functions where it is possible to calculate at least one element.

The paradox of the situation is that if we make a similar template by attaching the MA and Bollinger bands to any indicator (price line), we will not see such slowsdown of initial calculation of all history bars, like when using these functions in the code, when restarting the terminal or switching the TF, so it is unclear what takes so long to calculate in these functions.

Is it slowing down even when using iMAOnArray? There should not be such a thing. As you were, there was a slowdown from StdOnArray (or BandsOnArray, I don't remember) the developers did not admit existence of the bug for a long time. Then all of a sudden it was fixed and it worked fast. Who knows, maybe the bug returned. If iMAOnArray() causes noticeable slowdowns too, it is a bug. It seems that there were talks about it a couple of months ago... But it's still there, apparently.

 
Dmitry Fedoseev:

The slowdown even from using iMAOnArray? It shouldn't be like that. As you were at one time, there was a slowdown from StdOnArray, the developers did not acknowledge the bug for a long time. Then they suddenly fixed it and it worked fast. Who knows, maybe the bug returned. If iMAOnArray() causes noticeable slowdowns too, it is a bug. It seems that there were talks about it a couple of months ago... But it's still there, apparently.

It's hard to judge whether it "slows down much" or is acceptable, because everything depends on chart length (number of bars), the catch is that for optimization we only need to calculate a bit, but limiting the calculation length in fact is impossible.
 
Sergey Efimenko:
It's hard to judge whether it's too slow or not, because it all depends on the chart length (number of bars), the problem is that for optimization you only need to calculate a little bit, and you can't limit the length of calculation by actual calculation.
Do the calculation onMovingAverages.mqh and it's very fast.
 
forexman77:
Do the calculation withMovingAverages.mqh and it will calculate very quickly.
And this library calculates correctly, if you set calculation not of all array, but only of its last part (current values)? Besides, it's only half of the problem, but what about iBandsOnArray?
 
Sergey Efimenko:
So show me the "working" variant of the code, the original code is here, which you are trying to cut down to 12 displayed elements instead of the requested by me three hundred, and should end up with 3 indicator buffers with the specified data, so that at least 300 elements were displayed in the basement, And then, when a new bar comes, respectively, 301 and then the value will be drawn, but do not forget that in this case, if you use 0 as a limit for the calculation, only the new bar will be recalculated, and the type of average (smoothing) for the second buffer is not necessarily SMA, and can be any of the 4 available.

Here you go.

//+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 i, limit;
   limit = rates_total-prev_calculated-1;
   double buffer[];

   for(i = limit; i >= 0; i--)
     {
      Buffer[i]=open[i];
       ArrayCopy(buffer, Buffer, 0, i, 12);
      BufferMA[i] = iMAOnArray(buffer, 300, 12, 0, MODE_SMA, 0);
      BufferBMA[i] = iBandsOnArray(buffer, 300, 12, 2.0, 0, MODE_UPPER, 0);
      int x=0;
     }
   return(rates_total);
}
//+------------------------------------------------------------------+
Reason: