Errors, bugs, questions - page 3148

 
Roman #:

That's because IndBuff is not allocated to rates_total + 1
And ArrayResize is not applicable to it.
They broke the for construct. Do we have to use if-arses now?

for(int i=limit - 1;....

at least...

 
Roman #:

This is because the IndBuff is not allocated to rates_total + 1
and ArrayResize is not applicable to it.


This is where you need the minus 1 :))
The printout shows that the dimensions are OK.
Use logic:
If limit = 0, then it's a new tick.
If limit = 1, it means a new bar (the last element of the rates_total buffer is -1 and you have rates_total - hence the overflow)
If limit > 1, then it is better to re-calculate the entire indicator
 
Maxim Kuznetsov #:

for(int i=limit - 1;....

at the very least...

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.

 
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.

Everything is as it was before.
Your fault.
Tip - learn to use the debugger and you do not have to do proofreading, you will see all your faults at once.
 
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.

I have not noticed any changes in the calculation of indicators. As you've seen above, Nikolay has rightly explained what the limit values calculated as rates_total-prev_calculated mean.

And it has been working for years - since the fourth terminal.

 
Nikolai Semko #:
This is where you need the minus one :))
The printout shows that the dimensions are OK.
Use logic:
If limit = 0, then a new tick
If limit = 1, it means a new bar (the last element of the rates_total buffer is -1, and you have rates_total, hence the overflow)
If limit > 1, then it is better to re-calculate the entire indicator

Nikolay I know constructions if and for one,
but I always worked with for, I just got used to it, it's more convenient.
But I've noticed some strange things with for a long time ago and I've been putting off trying to figure it out.
It used to work fine before

for i>=0 ticks
for i>0 bars

And no ifs were needed.

 
Roman #:



Step 1: Create a template using 'MQL5 Wizard':

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,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[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Step 2: Spell 'limit' correctly and USE the close array - NOT the iClose call!!!

//+------------------------------------------------------------------+
//|                                                       Simple.mq5 |
//|                              Copyright © 2022, Vladimir Karputov |
//|                      https://www.mql5.com/en/users/barabashkakvn |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2022, Vladimir Karputov"
#property link      "https://www.mql5.com/en/users/barabashkakvn"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Close
#property indicator_label1  "Close"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      Input1=9;
//--- indicator buffers
double         CloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CloseBuffer,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 limit=prev_calculated-1;
   if(prev_calculated==0)
      limit=0;
   for(int i=limit; i<rates_total; i++)
     {
      CloseBuffer[i]=close[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


Result:

And there are no errors.

Files:
Simple.mq5  5 kb
 
Vladimir Karputov #:

Step 1: Create a template using 'MQL5 Wizard':


Step 2: Spell 'limit' correctly and USE the close array - NOT the iClose call!!!


Result:

and there are no errors.

Thanks for the direct i++ example of course.
But the fact that I have a reverse loop, you haven't noticed.
And if iClose is cited as an example, it must be used to show that the i index will be subsequently used in other functions.

 
Roman #:

Nikolai I know the constructions of if and for one,

else if

Nikolai Semko #:
Use logic:
If limit = 0, then a new tick
If limit = 1, it means a new bar (the last element of the rates_total buffer is -1, and you have rates_total, hence the overflow)
If limit > 1, then it is better to re-calculate the whole indicator

this is where
is wrong - better use
if limit != 1

So the whole logic is roughly what it is:

limit = rates_total - prev_calculated;
if (limit == 0) {..} // новый тик
else if ( limit == 1) {..} // новый бар
else {..} // полный пересчет всего индикатора
I understand that some people will be indignant and say why should I recalculate everything if limit == 2,
but when limit is not equal to 1 and not equal to 0, it means that this is the first initialization of indicator or something went wrong (for example, connection failure or server failure)
Moreover, many times I came across situations when prev_calculated was higher than rates_total. Probably, it was some glitch before and it was fixed now, but since then I use this design as a safety precaution.
 
Nikolai Semko #:

if limit != 1

What difference does it make? Can it get less than zero?