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

 
PolarSeaman:

It's still kicking out.

you have[i+1], you need to check +2 more

In general, you should do something like this

limit=(rates_total<cb || cb<=0) ? rates_total-1 : cb;
if (limit<=0) return(0);
 
Ihor Herasko:

Because the check is fundamentally wrong. Let's say Bars returns 1000 and cb also returns 1000. Then in the loop on the first iteration i gets the value 1000. In the first condition of the loop body:

two exits outside the array at once : accessing a bar with index 1000 and one with index 1001. For if the chart has 1000 bars, the first bar has index 0 and the last one has index 999.

Further on through the loop body there is a reference to the even more distant bars in the history:

All of this needs to be taken into account in the initial check.

For a proper check, see the example of the IndicatorCounted() function in MQL4 Reference. Only now, IndicatorCounted() should be replaced by sharing rates_total (this is Bars) and prev_calculated (this is IndicatorCounted()).

Thanks, Found it,

 int counted_bars=IndicatorCounted(); 
     if(counted_bars>0) counted_bars--;

What should I compare it to? in the example it starts withlimit

 limit=Bars-counted_bars;

What should i compare this "cb" with?

 
PolarSeaman:

Thank you, Found it,

What do I compare it to? In the example, it starts withlimit.

what should i compare this "cb" with?

If you want to limit the number of bars on which the indicator data is displayed, you'd better do it this way:

int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - 2 - barsig;                                                                         
                                                   
   if (cb > 0 && cb < total)
      total = MathMin(cb, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      InitializeBuffers();    // Это функция, которая должна заново инициализировать все индикаторные буфера, т. к. имеем дело с первой загрузкой индикатора или подкачкой истории
      return (total);
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}

Use as follows:

int total;   
int limit = GetRecalcIndex(total, rates_total, prev_calculated);                                

for (int i = limit; i >= 0; --i)
{
  ...
}
The total value is the index of the deepest bar in the history, which can be accessed based on the values of the indicator's settings.
 
Taras Slobodyanik:

you have[i+1], you need to check +2 more

In general, you should do something like this

I did it that way, but it says ...array out of range in 'HiLo.mq4' (122,15)

what should I check by +2 more?


 
Ihor Herasko:

If you want to limit the number of bars on which the indicator data is displayed, it is better to do so:

Use as follows:

The value of total is the index of the deepest bar in the history, which can be called based on the values of the indicator settings.

The compiler swears.

'InitializeBuffers' - function not defined HiLo.mq4 161 7

and there is nothing about this function in the help
 
PolarSeaman:

The compiler complains about

'InitializeBuffers' - function not defined HiLo.mq4 161 7

And there is nothing about this function in help

I wrote in the comment that this is a function that should initialize all the indicator buffers. It is a custom function. I have it like this:

void InitializeBuffers()
{
   ArrayInitialize(g_indValues, EMPTY_VALUE);
   ArrayInitialize(g_tempBuffer, EMPTY_VALUE);
}

You will have a different one as the buffers are different. In case the indicator works with graphical objects, you need to remove all of them here, because the initial drawing of the readings is to be done.

 
Ihor Herasko:

I wrote in the comment that this is the function that should initialise all the indicator buffers. It is a custom function. I have it like this:

You will have a different one, as the buffers are different. In case the indicatorworks with graphical objects, you have to delete all of them here, as the initial drawing of the readings is to be done.

Thanks, but nothing has changed ...array out of range in 'HiLo.mq4' (130,15)

. What is wrong?

#property copyright "Copyright ©  november 2015"
#property strict 

#property indicator_chart_window
#property indicator_buffers 6

#property indicator_color1 RoyalBlue       //DodgerBlue
#property indicator_color2 Crimson         //OrangeRed
#property indicator_color3 Black  //White
#property indicator_color4 Black  //White
#property indicator_color5 Black            //White
#property indicator_color6 Black         //Red

#property indicator_width1 2
#property indicator_width2 2

#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT

input int    p        = 10;    // Период
input int    s        = 5;     // Угол наклона
input double distance = 2.0;   // Ширина канала
input bool   showBb   = false;  // Границы канала
input bool   showCl   = true;  // Центральная линия
input int    barsig   = 1;     // Сигнальная свеча (номер)
input int    arrots   = 0;    // Стрелка (отступ)
input int    arrsz    = 0;     // Стрелка (размер)
input int    ATR      = 1000;  // Период ATR
input int    cb       = 1000;  // Сколько свечей в истории

double fx1[],fx2[],hp[];
double z1,z2,ki;
int fs;

double upper[],lower[];
double upar[],dnar[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- indicator buffers mapping
IndicatorBuffers(7);
SetIndexBuffer(0,fx1);
SetIndexBuffer(1,fx2);
SetIndexBuffer(2,lower);
SetIndexBuffer(3,upper);
SetIndexBuffer(4,upar);
SetIndexBuffer(5,dnar);
SetIndexBuffer(6,hp);


SetIndexStyle (4,DRAW_ARROW,0,arrsz);
SetIndexArrow (4,233);
SetIndexStyle (5,DRAW_ARROW,0,arrsz);
SetIndexArrow (5,234);

   if(showBb)
   {SetIndexStyle(2,DRAW_LINE);
    SetIndexStyle(3,DRAW_LINE);
   }
   else
   {SetIndexStyle(2,DRAW_NONE);
    SetIndexStyle(3,DRAW_NONE);
   }
   
    if(showCl)
   {SetIndexStyle(0,DRAW_LINE);
    SetIndexStyle(1,DRAW_LINE);
   }
   else
   {SetIndexStyle(0,DRAW_NONE);
    SetIndexStyle(1,DRAW_NONE);
   }

SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);

//---
   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<cb || cb<=0) ? rates_total-2 : cb;
//if (limit<=0) return(0);
 int total;   
 limit = GetRecalcIndex(total, rates_total, prev_calculated);                                

for (int i = limit; i >= 0; --i)
{ 
  
  
   SetIndexDrawBegin(0,Bars-cb);
   SetIndexDrawBegin(1,Bars-cb);

double avg;

ki=2.0/(p+1);

for (i=cb; i>=0; i--) {fx1[i]=Close[i];}

for (int m=0; m<=s; m++)
{
z1=fx1[0];
for (i=0; i<=cb; i++) {z1=z1+(fx1[i]-z1)*ki; hp[i]=z1;}

z2=fx1[cb];
for (i=cb; i>=0; i--) {z2=z2+(fx1[i]-z2)*ki; fx1[i]=(hp[i]+z2)/2;}
}

fs=0;
for (i=cb; i>=0; i--)
{
if (fx1[i]>fx1[i+1]) fs=1;
if (fx1[i]<fx1[i+1]) {if (fs==1) fx2[i+1]=fx1[i+1]; fs=2;}
if (fs==2) fx2[i]=fx1[i]; else fx2[i]=0.0;

avg = iATR(NULL,0,ATR, i+10);
upper[i] = hp[i] + distance*avg;
lower[i] = hp[i] - distance*avg;

if(Close[i+1+barsig]<upper[i+1+barsig] && Close[i+barsig]>upper[i+barsig])
 dnar[i] = High[i]+arrots*Point; else dnar[i] = EMPTY_VALUE;
 
if(Close[i+1+barsig]>lower[i+1+barsig] && Close[i+barsig]<lower[i+barsig])
 upar[i] = Low[i]-arrots*Point; else upar[i] = EMPTY_VALUE; 
}
}
//--- return value of prev_calculated for next call
   return(rates_total);
  }
  

int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - 2 - barsig;                                                                         
                                                   
   if (cb > 0 && cb < total)
      total = MathMin(cb, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      InitializeBuffers();    // Это функция, которая должна заново инициализировать все индикаторные буфера, т. к. имеем дело с первой загрузкой индикатора или подкачкой истории
      return (total);
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}

void InitializeBuffers()
{
   ArrayInitialize(fx1, EMPTY_VALUE);
   ArrayInitialize(fx2, EMPTY_VALUE);
   ArrayInitialize(lower, EMPTY_VALUE);
   ArrayInitialize(upper, EMPTY_VALUE);
   ArrayInitialize(upar, EMPTY_VALUE);
   ArrayInitialize(dnar, EMPTY_VALUE);
   ArrayInitialize(hp, EMPTY_VALUE);
}
 
PolarSeaman:

Thank you, but nothing has changed. What's wrong?

Of course, the result will not change. After all, you haven't removed the main reason (the cb loop). This loop is organized incorrectly:

for (i=cb; i>=0; i--)

It should be removed and replaced with the limit loop. In both places.

 
Ihor Herasko:

Of course, the result will not change. After all, you haven't removed the main reason (the cb loop). This loop is organized incorrectly:

It should be removed and replaced with the limit loop. In both places.

There are 3 such loops. I replaced them and the terminal hung.

 

I did it, it doesn't freeze or crash, but there are 3 values in the first buffer (fx2): price, 0.0 and 164874239.218492.

sell_1_B=NormalizeDouble(iCustom(Symbol(),0,"HiLo",1,1),Digits);

If value sell_1_B!=EMPTY_VALUE and sell_1_B!=0 it does not mean there is a price.

How do I get a signal?