Errors, bugs, questions - page 3151

 
Artyom Trishkin #:

There has always been a check: if(limit>1) limit=rates_total-1. This is for cases where there is no i+something in the calculation. If there is, then these "how many-something" must be included in the construct: limit=rates_total-1-some-something.

Without it, there would always be an array overrun. Because rates_total is nothing else but Bars(). Correspondingly, if there are 5000 bars and we address index 5000, we will fall outside the array's limits (the calculation of bars starts with zero).

In your example, the calculation of limit is wrong:

It should be like this:

And after it check for limit>1

And if limit is greater than one then limit = rates_total-1

Thanks Artem! And sorry for the fuss.
Right, there should be a check, I just forgot about it.
I still have a comment in the code
//Check and calculate the number of calculated bars.
Apparently, the copy-paste has caused my misunderstanding.
Everything works as it should with the check. Thank you.

 
Roman #:

Thanks Artem!
Right, there should be a check, which I had forgotten about.
Everything works properly with the check. Thank you.

You're welcome. Fix the calculation. It's not correct - I stressed it above.

int limit = rates_total-1-prev_calculated;

-1 should not be here.

If rates_total is 5000, and bars calculated on previous call of OnCalculate() are also 5000 (prev_calculated), then the limit will be equal to -1. Accordingly, the loop will not be executed at all.

If you want to select how to read the indicator (by ticks on the zero bar or only at opening of a new one), then enter a variable, specifying how to do it:

int end = (every tick ? WRONG_VALUE : 0);

the loop will be as follows: for(int i=limit; i>end; i--) { //... }

and the limit calculation will be correct, and the loop will be as you want it to be.

 

Correct code.

i>=0 for each tick

i>0 for new bar

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate (const int rates_total,       
                 const int prev_calculated,   
                 const int begin,             
                 const double& price[])      
{
   ArraySetAsSeries(price, true);
   ArraySetAsSeries(IndBuff, true);
   
   //-------------------------------------------------------------------------
   //Расчёт и проверка количества просчитываемых баров
   int limit = rates_total-prev_calculated;
   
   if(limit>1) 
      limit = rates_total-1;
   

   //-------------------------------------------------------------------------
   //Расчёт индикатора
   for(int i=limit; i>=0; i--)
   {

      IndBuff[i] = price[i]; 

   }
   

   return(rates_total);
}
 
Nikolai Semko #:
Or

You didn't even ask what to do... Are the telepaths back from holiday? ;)

 
Roman #:

Correct code.

i>=0 for each tick

i>0 for a new bar

ArraySetAsSeries(IndBuff, true);

This is better moved into OnInit()

 
Artyom Trishkin #:

You didn't even ask what to do... Are the telepaths back from holiday? ;)

:)
Artem, you don't need to be a telepath to see that the man registered a few minutes ago and the first thing he saw was "Bugs, bugs, questions"
Clearly, he's asking if he can get some free money, and not to make too much trouble...

 
Nikolai Semko #:

:)
Artem, you don't need to be a telepath to see that the man registered a few minutes ago and the first thing he saw was "Errors, bugs, questions"
Clearly, he is asking if he can get some money for free, and not to try too hard...

Maybe he decided to make some extra money on Bentley by investing into a tutor? :)

 
Artyom Trishkin #:

Maybe he decided to make some money for his Bentley by investing in a tutor, by hard work as a programmer. :)

I don't think so, Artem.
If he had the potential of a programmer, he wouldn't have allowed for ambiguity and uncertainty.
:)
 
Roman #:

You know what's most annoying? That any behaviour is cheated on silently, without warning.
And then people get hurt. I'm sick of this metatrader.

The design of an indicator cycle is just borrowed from the old days by copy-paste method (and crooked autocomplete) without thinking.

everything is simple with the current interface:

for(int bar=prev_calculated>0?prev_calculates-1:0 ; bar<rates_total; bar++) {

   int i=rates_total-1; // i используем если обращения как ArraySetSeries(x,true), иначе bar

   ....

}

return rates_total;

the push with prev_calculated-1 in this case is needed if you need to recalculate the last bar on each call.

 
Maxim Kuznetsov #:

It's just that the design of the indicator cycle is taken from the old days of copy-paste (and crooked autocompletion) without thinking.

everything is simple with the current interface:

for(int bar=prev_calculated>0?prev_calculates-1:0 ; bar<rates_total; bar++) {

   int i=rates_total-1; // i используем если обращения как ArraySetSeries(x,true), иначе bar

   ....

}

return rates_total;

the crowding with prev_calculated-1 in this case is needed if you need to recalculate the last bar on each call.

Yes, I got a bit excited with my statement.
Just when something used to work and now doesn't, nervous tics start ))
And you start to double-check everything and groundlessly blame the crash, forgetting about some peculiarity you certainly don't remember.
And copypaste is to blame. I think many have faced this.

I want to suggest that the developers make custom templates for indicators and EAs.
They will be able to select them in the wizard.

m

Some C/C++ editors have this feature.
It's very convenient to add the basic templates, with which you mainly work, and then you loading them in the wizard.
Standard MQL templates are not quite the same at all.
Obviously, we can say that we can write templates and then copy them.
And again we come back to the insidious word "copy-paste". And the fact that we can automate it and make the programmer's life easier is not taken into account.

Reason: