Weird kinks in my custom ZigZag indicator

 

Heya,

I'm currently working towards my own ZigZag indicator.

Right now it just looks for a bullish candle followed by a bearish one and vice versa. It then stores a high or low in the indicator buffer.

Even though the logic is simple, the indicator sometimes stores a value even when there's no 'pivot'. Some 'pivots' are also missed.

Can anybody help out? I can't figure out what's causing this. I attached the indicator below.

Thank you!

//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_SECTION
#property indicator_color1  Blue
#property indicator_label1  "ZigZag2"
//---- indicator buffers
double pivots[];
//---

int OnInit()
  {
   //--- indicator buffers mapping
   SetIndexBuffer(0,pivots,INDICATOR_DATA);
   //--- sets the accuracy of the indicator
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   //--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,10);
   //--- sets drawing shift
   PlotIndexSetInteger(0,PLOT_SHIFT,1);
   //--- sets the empty value to filter out
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
   //--- end of the OnInit function
   return(INIT_SUCCEEDED);
  }

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;
   double direction = 0;
   for (i = bars_loaded() - 3; i >= 0; i--)
      {
      if(direction == 0)
         {
         if(open[i+2] > close[i+2] && open[i+1] < close[i+1])
            {
            pivots[i] = low[i+1];
            direction = 1;
            continue;
            } 
         else if(open[i+2] < close[i+2] && open[i+1] > close[i+1])
            {
            pivots[i] = high[i+1];
            direction = -1;
            continue;
            }
         else
            {
            pivots[i] = EMPTY_VALUE;
            continue;
            }      
         }
      else if(direction == 1)
         {
         if(open[i+2] < close[i+2] && open[i+1] > close[i+1])
            {
            pivots[i] = high[i+1];
            direction = -1;
            continue;
            }
         else
            {
            pivots[i] = EMPTY_VALUE;
            continue;
            }      
         }
      else if(direction == -1)
         {
         if(open[i+2] > close[i+2] && open[i+1] < close[i+1])
            {
            pivots[i] = low[i+1];
            direction = 1;
            continue;
            }
         else
            {
            pivots[i] = EMPTY_VALUE;
            continue;
            }
         }    
      }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
int bars_loaded()
   {
   int amount_of_bars = Bars(Symbol(), Period());
   return(amount_of_bars);
   }

Files:
CW_ZigZag2.ex5  13 kb
 
CodeWitch:

Heya,

I'm currently working towards my own ZigZag indicator.

Right now it just looks for a bullish candle followed by a bearish one and vice versa. It then stores a high or low in the indicator buffer.

Even though the logic is simple, the indicator sometimes stores a value even when there's no 'pivot'. Some 'pivots' are also missed.

Can anybody help out? I can't figure out what's causing this. I attached the indicator below.

Thank you!


Post the code if you need help.
 
Okay, I edited my post to include the code. You can also find it in the attachments
 
  1. Direction is a variable value from the previous iteration, which means you can't process bar zero more than once, ever. Put it in a buffer so you can restore it, or only process bar zero once, or save and restore them when processing bar zero.

  2. You are processing all bars per tick. Code it properly so it only recomputes bar zero (after the initial run.)
              How to do your lookbacks correctly.

  3. Unlike MT4's Open/Close/etc., the variables open/close/etc do not have a direction defined. Where do you set them as series before using them?
    To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
              https://www.mql5.com/en/docs/basis/function/events#oncalculate2
 
whroeder1:
  1. Direction is a variable value from the previous iteration, which means you can't process bar zero more than once, ever. Put it in a buffer so you can restore it, or only process bar zero once, or save and restore them when processing bar zero.

  2. You are processing all bars per tick. Code it properly so it only recomputes bar zero (after the initial run.)
              How to do your lookbacks correctly.

  3. Unlike MT4's Open/Close/etc., the variables open/close/etc do not have a direction defined. Where do you set them as series before using them?
Thanks for the help. I'll try and apply your tips tomorrow!
 

I managed to create an indicator that draws like it's supposed to. I left 'direction' out, but the simpler logic seems to work fine.

Thanks for helping!