Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 1445

 
Vitaly Muzichenko:

Thank you!

Tried it and got an error, I'm doing something wrong:

Is buffer[] distributed? I see the declaration, but I don't see the size setting

 
Artyom Trishkin:

Is buffer[] distributed? I see the declaration, but I don't see the size set

Set size, error somewhere else, doesn't work.

 
Vitaly Muzichenko:

Set size, error somewhere else, doesn't work.

What are you transmitting?

 
Artyom Trishkin:

What are you passing on?

   double Array_1[];
   double Array_2[];
   ArraySetAsSeries(close, true);
   int count = rates_total-1;
   if(count < 0)
      return (-1);
   int i = 1;
   int period = (int)MathFloor(MathSqrt(a));
   int val_1 = (int)MathFloor(a / 1.9);
   int counter = Bars(_Symbol,_Period) - count + a + 1;
   if(counter > Bars(_Symbol,_Period))
      counter = Bars(_Symbol,_Period);
  // ArraySetAsSeries(Array_1, true);
   ArrayResize(Array_1, counter);
  // ArraySetAsSeries(Array_2, true);
   ArrayResize(Array_2, counter);
   double d_close = close[1];
   double buff[];
   ArrayResize(buff, counter);
   for(i = 0; i < counter; i++)
      Array_1[i] = 2.0 * ma_1(i, val_1) - ma_1(i, a);
   for(i = 0; i < counter - a; i++) {
      // buf_3[i] = iMAOnArray(Array_1, 0, period, 0, MODE_SMMA, i);
      // buf_3[i] = iMA(NULL, 0, period, 0, MODE_SMMA, PRICE_LOW);
      //  CopyBuffer(10,0,i,1,buff);
      SmoothedMAOnBuffer(counter, prev_calculated, i, period, Array_1, buff);
      buf_3[i] = buff[0];
      }
     .....

//+------------------------------------------------------------------+
int SmoothedMAOnBuffer(const int rates_total,const int prev_calculated,const int begin,const int period,const double& price[],double& buffer[])
{
//--- check period
   if(period<=1 || period>(rates_total-begin))
      return(0);
//--- save as_series flags
   bool as_series_price=ArrayGetAsSeries(price);
   bool as_series_buffer=ArrayGetAsSeries(buffer);
   ArraySetAsSeries(price,false);
   ArraySetAsSeries(buffer,false);
//--- calculate start position
   int start_position;
   if(prev_calculated==0) { // first calculation or number of bars was changed
      //--- set empty value for first bars
      start_position=period+begin;
      for(int i=0; i<start_position-1; i++)
         buffer[i]=0.0;
      //--- calculate first visible value
      double first_value=0;
      for(int i=begin; i<start_position; i++)
         first_value+=price[i];
      buffer[start_position-1]=first_value/period;
   } else
      start_position=prev_calculated-1;
//--- main loop
   for(int i=start_position; i<rates_total; i++)
      buffer[i]=(buffer[i-1]*(period-1)+price[i])/period;
//--- restore as_series flags
   ArraySetAsSeries(price,as_series_price);
   ArraySetAsSeries(buffer,as_series_buffer);
//---
   return(rates_total);
}
 
Vitaly Muzichenko:

Vitaly, why copy the function from the inluder? Wouldn't it be easier to plug in a library?

#include <MovingAverages.mqh>
 
Vitaly Muzichenko:

In general, remove the call to this function from the loop. There is already a full loop in this function. In begin you need to pass the beginning of significant data in the array, based on which you are doing smoothing. For some types of smoothing you need a pre-calculation. For SMMA it is about two calculation periods.

 
Artyom Trishkin:

In general, remove the call to this function from the loop. There is already a full loop in this function. In begin you need to pass the beginning of significant data in the array, based on which you are doing smoothing. For some types of smoothing you need a pre-calculation. For SMMA it is about two calculation periods.

But when a new bar is added, won't the entire array be recalculated? And when the current value in the array changes, the buffer would also need to be recalculated. In this case, how can we avoid the loop?

Once at the start of the indicator, through the entire buffer, and then only the last index on each tick? This is an impromptu. I haven't done so yet... I have to check it.

 
Alexey Viktorov:

And in this case, when a new bar is added, won't the whole array be recalculated? And it wouldn't hurt to recalculate when the current value in the buffer array changes, either. In this case, how can we avoid the loop?

Once at the start of the indicator, through the entire buffer, and then only the last index on each tick? This is an impromptu. I haven't done so yet... I have to check it.

Well, look at the code - Vitaly has directly laid it out

 
Artyom Trishkin:

Well, look at the code - Vitaly posted it directly

Now I came to debug "SmoothedMAOnBuffer()" construct in mt4.

I don't understand what's wrong

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[])
{
   double Array_1[];
   double Array_2[];
   int count = IndicatorCounted();
   if(count < 0)
      return (-1);
   int i = 1;
   int period = (int)MathFloor(MathSqrt(a));
   int val_1 = (int)MathFloor(a / 1.9);
   int counter = Bars - count + a + 1;
   if(counter > Bars)
      counter = Bars;
   ArraySetAsSeries(Array_1, TRUE);
   ArrayResize(Array_1, counter);
   ArraySetAsSeries(Array_2, TRUE);
   ArrayResize(Array_2, counter);
   double d_close = close[1];
   double buff[];
   ArrayResize(buff, counter);
   for(i = 0; i < counter; i++)
      Array_1[i] = 2.0 * ma_1(i, val_1) - ma_1(i, a);
   for(i = 0; i < counter - a; i++) {
     // buf_3[i] = iMAOnArray(Array_1, 0, period, 0, MODE_SMMA, i); // Так индикатор работает
      SmoothedMAOnBuffer(counter, prev_calculated, i, period, Array_1, buff); Совсем не работает, но и ошибок в журнале нет
      buf_3[i] = buff[0]; ???
   }
   for(i = counter - a; i > 0; i--) {
      Array_2[i] = Array_2[i + 1];
      if(buf_3[i] > buf_3[i + 1])
         Array_2[i] = 1;
      if(buf_3[i] < buf_3[i + 1])
         Array_2[i] = -1;
      if(Array_2[i] > 0.0) {
         buf_1[i] = buf_3[i];
         if(Array_2[i + 1] < 0.0)
            buf_1[i + 1] = buf_3[i + 1];
         if(Array_2[i + 1] < 0.0) {
         }
         buf_2[i] = EMPTY_VALUE;
      } else {
         if(Array_2[i] < 0.0) {
            buf_2[i] = buf_3[i];
            if(Array_2[i + 1] > 0.0)
               buf_2[i + 1] = buf_3[i + 1];
            if(Array_2[i + 1] > 0.0) {
            }
            buf_1[i] = EMPTY_VALUE;
         }
      }
   }
   for(i = 0; i < counter-1; i++) {
      if(buf_2[i + 1] == EMPTY_VALUE && buf_2[i] != EMPTY_VALUE)
         buf_4[i] = buf_2[i];
      if(buf_1[i + 1] == EMPTY_VALUE && buf_1[i] != EMPTY_VALUE)
         buf_5[i] = buf_1[i];
   }
   return(rates_total);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int SmoothedMAOnBuffer(const int rates_total,const int prev_calculated,const int begin,const int period,const double& price[],double& buffer[])
{
//--- check period
   if(period<=1 || period>(rates_total-begin))
      return(0);
//--- save as_series flags
   bool as_series_price=ArrayGetAsSeries(price);
   bool as_series_buffer=ArrayGetAsSeries(buffer);
   ArraySetAsSeries(price,false);
   ArraySetAsSeries(buffer,false);
//--- calculate start position
   int start_position;
   int i=0;
   if(prev_calculated==0) { // first calculation or number of bars was changed
      //--- set empty value for first bars
      start_position=period+begin;
      for(i=0; i<start_position-1; i++)
         buffer[i]=0.0;
      //--- calculate first visible value
      double first_value=0;
      for(i=begin; i<start_position; i++)
         first_value+=price[i];
      buffer[start_position-1]=first_value/period;
   } else
      start_position=prev_calculated-1;
//--- main loop
   for(i=start_position; i<rates_total; i++)
      buffer[i]=(buffer[i-1]*(period-1)+price[i])/period;
//--- restore as_series flags
   ArraySetAsSeries(price,as_series_price);
   ArraySetAsSeries(buffer,as_series_buffer);
//---
   return(rates_total);
}
 
Vitaly Muzichenko:

Now I've come to debugging the "SmoothedMAOnBuffer()" construct in mt4.

What's wrong, I don't understand it at all

Remove from the loop
Reason: