What the Lowest and Highest functions return - page 5

 
Candid I'm fine now.
Klot, interesting option.

If your zigzag variants show interesting results, can I apply them in my development?

Of course you can, I am following the development with interest and I like your work very much.
 
Thank you.
 
2 nen:
More regarding "options". Now one of the conditions for extremum switching: current low is higher than current low by more than ExtDeviation points (similar for high). The code allows to implement other options quite easily, if necessary.
Well, following klot I would like to add that my current interest in the zigzag is caused solely by my interest in your design.
 
Corrected the source code again - yesterday I found out that the first significant bar rule is sometimes not respected on minutes. To check it, I only had an hour and a half of online time, but it seems that it was a matter of comparing double with zero.
 
Another bug: Extremes can only be switched at the end of a bar, otherwise there is a difference between real time and history. It is not difficult to fix. I have not corrected the source code in the branch yet - let the new version run on minutes.
 
Candid, made a 45 version of the ZUP indicator: http://onix-trade.net/forum/index.php?s=&showtopic=118&view=findpost&p=117997
Included your zigzag as an external zigzag. As soon as a stable working version appears, I will change it.
 
So far I don't see any problems, here is the corrected version of the code:
//+------------------------------------------------------------------+
//|                                                      CZigZag.mq4 |
//|                                         Copyright © 2006, Candid |
//|                                                   likh@yandex.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Candid"
#property link      "likh@yandex.ru"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Navy

//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
//extern int ExtBackstep=3;

int    shift;
double res=0;
int i;
double CurMax,CurMin;
int CurMaxPos,CurMinPos;
int CurMaxBar,CurMinBar;
double hPoint;
double mhPoint;
double EDev;
int MaxDist,MinDist;
bool FirstRun;
bool AfterMax,AfterMin;
int BarTime;

//---- indicator buffers
double ZigZag[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {
//---- indicators
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ZigZag);
   SetIndexEmptyValue(0,0.0);
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+")");
   
   FirstRun = true;
//----
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {
//----
   
//----
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
  int counted_bars=IndicatorCounted();
  int fBar;
  
  if (FirstRun) {
    hPoint = 0.5*Point;
    mhPoint = -hPoint;
    EDev = (ExtDeviation+0.5)*Point;
    AfterMax = true;
    AfterMin = true;
    fBar = Bars-1;
    CurMax = High[fBar];
    CurMaxBar = 1;
    CurMin = Low[fBar];
    CurMinBar = 1;
    MaxDist = 0;
    MinDist = 0;
    BarTime = 0;
    FirstRun = false;
  }


//----
  fBar = Bars-counted_bars-1;
  if (fBar > Bars-2) fBar = Bars-2;
  for(shift=fBar; shift>=0; shift--) {
    if (BarTime!=Time[shift]) {
      BarTime=Time[shift];
      if (res > hPoint ) {
        MaxDist = Bars-CurMaxBar-shift+1;
        MinDist = Bars-CurMinBar-shift+1;
        if ((MaxDist>ExtDepth && MinDist>ExtDepth) || res > EDev) {
          if (AfterMax) {
            AfterMax = false;
            AfterMin = true;
            CurMaxBar = CurMinBar+1;
            CurMaxPos = Bars-CurMaxBar;
            CurMax = High[CurMaxPos];
            for (i=CurMaxPos-1;i>=shift;i--) {
              if (High[i] > CurMax+hPoint) {
                CurMaxBar = Bars-i;
                CurMax = High[i];
              }
            }  //  for (i=CurMaxPos-1;i>=shift;i--)
            ZigZag[Bars-CurMaxBar] = CurMax;
          } else {  //  if (AfterMax)
            AfterMin = false;
            AfterMax = true;
            CurMinBar = CurMaxBar+1;
            CurMinPos = Bars-CurMinBar;
            CurMin = Low[CurMinPos];
            for (i=CurMinPos-1;i>=shift;i--) {
              if (Low[i] < CurMin-hPoint) {
                CurMinBar = Bars-i;
                CurMin = Low[i];
              }
            }  //  for (i=CurMinPos-1;i>=shift;i--)
            ZigZag[Bars-CurMinBar] = CurMin;
          }  //  else if (AfterMax)    
        }  //  if ((MaxDist>ExtDepth && MinDist>ExtDepth) || res > EDev)
      }  //  if (res > hPoint )
    }  //  if (BarTime!=Time[0])
    if (AfterMax) {
      res = Low[shift]-CurMin;
      if (res < mhPoint) {
        ZigZag[Bars-CurMinBar] = 0;
        CurMin = Low[shift];
        CurMinBar = Bars-shift; 
        ZigZag[Bars-CurMinBar] = CurMin;
      }  //  if (res < mhPoint)
    }  //  if (AfterMax) 
    if (AfterMin) {
      res = CurMax-High[shift];
      if (res < mhPoint) {
        ZigZag[Bars-CurMaxBar] = 0;
        CurMax = High[shift];
        CurMaxBar = Bars-shift; 
        ZigZag[Bars-CurMaxBar] = CurMax;
      }  //  if (res < mhPoint)
    }  //  if (AfterMin) 
  }  //  for(shift=fBar; shift>=0; shift--)
//----
  return(0);
}
//+------------------------------------------------------------------+


On the subject of the peculiarities of different zigzags. The main feature of this zigzag is that everything is done in one pass, the revisiting of historical data is done only when an extremum is fixed, and only for data after that extremum. That is, it must be quite fast. Particulars of drawing will of course depend on the criteria of extremum fixing but various options can easily be implemented here. For example, I have already made variants switching by percentage of a previous move, by departure of High from the minimum (respectively Low from the maximum) and binding the switch to the average bar size.

 
Here's another problem with the indicator: I found a kink in my zigzag (cursor cross in the picture). The time of the kink corresponds to when the terminal was switched off, the price corresponds to when it was switched back on.


To clarify my suspicions, I inserted the Print in the code:
if (shift<5) Print ("shift=",shift,", Bars=",Bars,", Time[shift]=",TimeToStr(Time[shift],TIME_DATE|TIME_MINUTES),", High[shift]=",High[shift],", Low[shift]=",Low[shift]);


The terminal was then closed and restarted a few minutes later. And here is a fragment of the log:

2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763 2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763 2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763 2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=1, Bars=38233, Time[shift]=2006.10.31 22:50, High[shift]=1.2763, Low[shift]=1.2762 2006.10.3131 23:58:26 CZZ2 EURUSD,M1: shift=2, Bars=38233, Time[shift]=2006.10.31 22:49, High[shift]=1.2763, Low[shift]=1.2763 2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=3, Bars=38233, Time[shift]=2006.10.31 22:47, High[shift]=1.2763, Low[shift]=1.2762 2006.10.31 23:58:26 CZZ2 EURUSD,M1: shift=4, Bars=38233, Time[shift]=2006.10.31 22:45, High[shift]=1.2763, Low[shift]=1.2762 2006.10.31 23:58:25 CZZ2 EURUSD,M1: shift=0, Bars=38230, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763 2006.10.31 23:58:25 CZZ2 EURUSD,M1: shift=1, Bars=38230, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762 2006.10.31 23:58:23 CZZ2 EURUSD,M1: shift=0, Bars=38229, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762 2006.10.31 23:58:22 CZZ2 EURUSD,M1: shift=0, Bars=38229, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762


You can see that at 23:58:23 the history was not pumped yet, and by 23:58:25 the last 1 bar was pumped. And only by 2006.10.31 23:58:26 all intermediate bars were pumped.
Question to the developers: is this the normal paging sequence? And if so, what is the point of it? Clearly, it is desirable to have the current price value early. But the planned existence of a hole in the history for some time essentially means a guaranteed failure of indicators for this time. Isn't it safer for the user to postpone the calculation of indicators until the history is completely swapped? Or at least re-initialize them after the full swap?

 
The "reinitialise" thing was a mistake, it would essentially be a trailblazer :)
 
I am familiar with this kind of history paging. I have done a check of the first five zigzag breaks AND a recalculation of the ZUP indicator.