[ARCHIVE]Any rookie question, so as not to clutter up the forum. Professionals, don't pass it by. Can't go anywhere without you - 5. - page 29

 
hoz:

Can you tell me how to draw values from a zig-zag indicator? How is this implemented in general? I.e. if I want to pick up a certain extremum, not just the last one.

For instance, now I want to attach this zigzag to my Expert Advisor:

I understand that I need to use theiCustom function as it is usually used to address a custom indicator, but the question is how to connect the nodes...

The buffer is looking for the NEUTRAL(EMPTY_VALUE) value according to the principle:

//+-------------------------------------------------------------------------------------+
//| Поиск последнего элемента ZZBuf с непустым значением                                |
//+-------------------------------------------------------------------------------------+
int GetLastIndexNoEmptyValue(int index)
{
   while (ZZBuf[index] == EMPTY_VALUE && index < Bars)// Поиск по графику справа налево
      index++;                                     // Пока не будет найден экстремум или
                                                   // ..пока не достигнем конца истории
   return(index);                                  // Индекс бара с непустым значением..
                                                   // ..зиг-зага
}
and access to the indicator buffer via iCustom().
 
TarasBY:

The buffer is looking for an EMPTY_VALUE value according to the principle:

//+-------------------------------------------------------------------------------------+
//| Поиск последнего элемента ZZBuf с непустым значением                                |
//+-------------------------------------------------------------------------------------+
int GetLastIndexNoEmptyValue(int index)
{
   while (ZZBuf[index] == EMPTY_VALUE && index < Bars)// Поиск по графику справа налево
      index++;                                     // Пока не будет найден экстремум или
                                                   // ..пока не достигнем конца истории
   return(index);                                  // Индекс бара с непустым значением..
                                                   // ..зиг-зага
}

and the indicator buffer is accessed via iCustom().


It makes sense. But it will be searched in this way until we come across a non-empty value. And if, for example, I, and, in fact, I want not the last nonempty value, i.e. not the last extremum, but another... For example, here in the screenshot:

 
hoz:


Makes sense. But this way the search will be until we come across a non-empty value. And if, for example, I, and, in fact, I want not the last nonempty value, i.e. not the last extremum, but another... For example, here in the screenshot:

One should introduce the counter of extrema into the loop and break the loop at the number of the extremum (nonempty value in a row).
 
TarasBY:
Enter an extremum counter in the loop and at the number of extremum (non-empty value in a row), break the loop.

Got it. Thank you. Now we need to apply all that in practice. I get the gist, but my mind is full of filters that make my brain boil...
 
hoz:

Got it. Thank you. Now we need to apply it in practice. I got the idea, but there are so many filters in my mind that my brain is boiling...

double get_extrem(int n) {

   for(int i=1;;i++) {

      double ind=iCustom(Symbol(),0,"indicator_name",0,i);

      if(n>1)  

         if(ind!=0) n--;

         else

         if(ind!=0) return(ind);

      }

   }


If you need the bar number of the peak, change the function type to int and instead of return(ind); write return(i);

Also note, if you use i in your code, especially in searches (like in tutorial) then change i in this function to any other variable, for example k.

And make sure to configure iCustom inside the function for your indicator.

 
keep87:

double get_extrem(int n) {

   for(int i=1;;i++) {

      double ind=iCustom(Symbol(),0,"indicator_name",0,i);

      if(n>1)  

         if(ind!=0) n--;

         else

         if(ind!=0) return(ind);

      }

   }


If you need the bar number of the peak, change the function type to int and instead of return(ind); write return(i);

Also note, if you use i in your code, especially in searches (like in tutorial) then change i in this function to any other variable, for example k.

And make sure to configure iCustom inside the function for your indicator.

Nikolay, it's interesting, of course, you have the condition written. I look at it and think...

if(ind!=0) n--;

else

if(ind!=0) return(ind);

It turns out that if the buffer of the custom indicator returned the value of zero, then n--, and if thebuffer of the custom indicator returned the value of zero, then ... we return the value of the indicator buffer.

But the conditions are the same. And there and so if not zero...

 
hoz:

Nikolai, it's interesting, of course, you have the condition written. As I look at it, I think...

It turns out that if the custom indicator buffer returned a value of zero, then n--, and if thecustom indicator buffer returned a value of zero, then ... we return the value of the indicator buffer.

But the conditions are the same. And there and so if not zero...

Braces fell out while trying to insert the code correctly:

double get_extrem(int n) {

   for(int i=1;;i++) {

      double ind=iCustom(Symbol(),0,"indicator_name",0,i);

      if(n>1) {

         if(ind!=0) n--;

         }else{

         if(ind!=0) return(ind);

         } 

      }

   }

If n>1 {

if the buffer is not empty, then subtract 1 from n

} the other way round{

if the buffer is not empty, return its value

}

 

double get_extrem(int n) {

   for(int i=1;;i++) {

      double ind=iCustom(Symbol(),0,"indicator_name",0,i);

      if(ind!=0) {

         if(n>1) n--; else return(ind);

         }

      }

   }


or like this, which is more succinct. I'm obsessed with speed and beauty of code, don't mind me )
 
keep87:

double get_extrem(int n) {

   for(int i=1;;i++) {

      double ind=iCustom(Symbol(),0,"indicator_name",0,i);

      if(ind!=0) {

         if(n>1) n--; else return(ind);

         }

      }

   }


or like this, which is more succinct. I'm obsessed with speed and beauty of code, don't mind me.)


In general, everything is fine in both ways. I'm just used to writing code a bit differently, it's easier to read this way while yours is different. The first bracket in each of your code does not move. I put it in my EDITOR and everything is in its place like that:

double get_extrem(int n)
{
   for(int i=1;;i++)
   {
     double ind=iCustom(Symbol(),0,"indicator_name",0,i);
       if(n>1)
        {
          if(ind!=0) n--;
        }
        else
        {
          if(ind!=0) return(ind);
        } 
   }
}
 
hoz:


Basically, everything is fine both ways. I'm just used to writing code in a different way: it is easier to read this way, while your code is different. The first bracket in each of your code does not move. I put it in Editor and everything is in its place in this form:


when the code goes over 1000 lines, you start writing compactly.)

also in MT4 the performance suffers, especially when running tests. The laconic version performs faster.