Help - Fibonnaci indicator that uses ZigZag

 

Hi,

I am trying to create a Fibonacci indicator that once put over a chart it uses the ZigZag to get the 3 consecutives (H,L,H) or (L,H,L) so I can use those values to draw a retracement and extension Levels.

Also that once I manually adjust the Fibo Levels it recalculates and updates the buffers.

I made some progress writing this indicator but I am kind stuck in that part of ZigZag use and redraw after manual adjustment.  The panel does not change its value if I manually replace my edges of Fibonacci.
For example, in the code it is commented

Só me interesso pelos níveis de 0.628 e 0.786 que são os índices 4 e 5 do array FibPriceLevelsRetracement

it means

I am just interested by levels of 0.628 e 0.786 that are the indexes 4 e 5 of array FibPriceLevelsRetracement

So, if I replace the edges of Fibo the indicator should also recalculate and verify if the candle crosses the fibo level in appropriate way and update the buffer and the panel.  The issue is that it does not do that.

I would like to share the code so everybody can contribute with it.

//+------------------------------------------------------------------+
//|                                                       ZigZag.mq4 |
//|                   Copyright 2006-2014, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2006-2014, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property strict
#property indicator_buffers 4       // Number of buffers
#property indicator_chart_window
#property indicator_color1 Red
#include <mt4gui2.mqh>

const string indicator_name = "FiboRetraction";

double retracementExtensionLevels[] = {0, 0.23, 0.382, 0.50, 0.618, 0.786, 1, 1.272, 1.618};
double expansionLevels[] = {0.38, 0.5, 0.628}; //Extrapolação a partir de AB
double pojectionLevels[] = {0.628, 1, 1.62};//Lightning picture

color LC = DodgerBlue; // Fib Line Color 
color LC_IMPORTANT = Red; // Fib Line Color 
ENUM_LINE_STYLE RETRACE_EXTENSION_LINE_STYLE = STYLE_DASH; // Style of lines
ENUM_LINE_STYLE EXPANSION_LINE_STYLE = STYLE_DASHDOTDOT; // Style of lines
int LW = 1; // Fib Line Width

double FibPriceLevelsRetracement[];
double FibPriceLevelsexpansion[];
double FibPriceLevelsProjection[];
double OutSideNotificationBuffer[];
bool redraw = true;
bool isHightoLow = false;

int hwnd = 0;

// Settings
int GUIX = 50;
int GUIY = 100;

// GUI Object Handles
int Label1,Label2;


int OnInit(){
   ArrayResize(FibPriceLevelsRetracement,9);
   ArrayInitialize(FibPriceLevelsRetracement,0);
   ArrayResize(FibPriceLevelsexpansion,5);
   ArrayInitialize(FibPriceLevelsexpansion,0);
   ArrayResize(FibPriceLevelsProjection,3);
   ArrayInitialize(FibPriceLevelsProjection,0);
   ArrayResize(OutSideNotificationBuffer,3);
   ArrayInitialize(OutSideNotificationBuffer,-1);

   SetIndexBuffer(0,FibPriceLevelsRetracement);
   SetIndexBuffer(1,FibPriceLevelsexpansion);
   SetIndexBuffer(2,FibPriceLevelsProjection);
   SetIndexBuffer(3,OutSideNotificationBuffer);
   
   ObjectsDeleteAll();
   hwnd = WindowHandle(Symbol(),Period());     
   // Lets remove all Objects from Chart before we start
   guiRemoveAll(hwnd);
   // Lets build the Interface
   BuildInterface(0);
   return(INIT_SUCCEEDED);
}
  
void OnDeinit(const int reason){
   ObjectDelete("XIT_FIBO");
   if (hwnd>0){
      guiRemoveAll(hwnd);
      guiCleanup(hwnd);
   }
}    

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[]){
   calculateFibonnaciRetracementAndExpansions();
   notifyOutside();
   return(rates_total);
}
//+------------------------------------------------------------------+
void calculateFibonnaciRetracementAndExpansions(){
   redraw = true;
   static int fibHigh = 0;
   static int fibLow  = 0;
   int tempHigh, tempLow = 0;
   tempHigh = iHighest(Symbol(),Period(),MODE_HIGH,21,1);
   tempLow = iLowest(Symbol(),Period(),MODE_LOW,21,1);
   if(fibHigh == tempHigh) redraw = false;
   if(fibLow == tempLow) redraw = false;
   fibHigh = tempHigh;
   fibLow = tempLow;
   
   datetime highTime = Time[fibHigh];
   datetime lowTime  = Time[fibLow];
   redraw = true;
   if(redraw){
      WindowRedraw();
      isHightoLow = true;
      if(fibHigh>fibLow){
         isHightoLow = true;
         ObjectCreate("XIT_FIBO",OBJ_FIBO,0,highTime,High[fibHigh],lowTime,Low[fibLow]);
      }
      else{
         isHightoLow = false;
         ObjectCreate("XIT_FIBO",OBJ_FIBO,0,lowTime,Low[fibLow],highTime,High[fibHigh]);
      }
      
      double fiboPrice1=ObjectGet("XIT_FIBO",OBJPROP_PRICE1);
      double fiboPrice2=ObjectGet("XIT_FIBO",OBJPROP_PRICE2);
      
      double fiboPriceDiff = fiboPrice2-fiboPrice1;
      for(int i=0;i<ArraySize(retracementExtensionLevels);i++){
         FibPriceLevelsRetracement[i] = NormalizeDouble(fiboPrice2-fiboPriceDiff*retracementExtensionLevels[i],Digits());
      }
      
      string fiboValue0 = DoubleToStr(FibPriceLevelsRetracement[0],Digits);
      string fiboValue23 = DoubleToStr(FibPriceLevelsRetracement[1],Digits);
      string fiboValue38 = DoubleToStr(FibPriceLevelsRetracement[2],Digits);
      string fiboValue50 = DoubleToStr(FibPriceLevelsRetracement[3],Digits);
      string fiboValue61 = DoubleToStr(FibPriceLevelsRetracement[4],Digits);
      string fiboValue79 = DoubleToStr(FibPriceLevelsRetracement[5],Digits);
      string fiboValue100 = DoubleToStr(FibPriceLevelsRetracement[6],Digits);
      string fiboValue127 = DoubleToStr(FibPriceLevelsRetracement[7],Digits);
      string fiboValue162 = DoubleToStr(FibPriceLevelsRetracement[8],Digits);
      
      ObjectSet("XIT_FIBO",OBJPROP_FIBOLEVELS,8);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+0,0.0);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+1,0.236);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+2,0.382);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+3,0.50);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+4,0.618);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+5,0.786);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+6,1.0);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+7,1.27);
      ObjectSet("XIT_FIBO",OBJPROP_FIRSTLEVEL+8,1.62);
      
      
      ObjectSet("XIT_FIBO",OBJPROP_LEVELCOLOR,LC);
      ObjectSet("XIT_FIBO",OBJPROP_LEVELWIDTH,1);
      ObjectSet("XIT_FIBO",OBJPROP_LEVELSTYLE,RETRACE_EXTENSION_LINE_STYLE);
      ObjectSetFiboDescription( "XIT_FIBO", 0,fiboValue0+" --> 0.0%"); 
      ObjectSetFiboDescription( "XIT_FIBO", 1,fiboValue23+" --> 23.6%"); 
      ObjectSetFiboDescription( "XIT_FIBO", 2,fiboValue38+" --> 38.2%"); 
      ObjectSetFiboDescription( "XIT_FIBO", 3,fiboValue50+" --> 50.0%");
      ObjectSetFiboDescription( "XIT_FIBO", 4,fiboValue61+" --> 61.8%");
      ObjectSetFiboDescription( "XIT_FIBO", 5,fiboValue61+" --> 78.6%");
      ObjectSetFiboDescription( "XIT_FIBO", 6,fiboValue100+" --> 100.0%");
      ObjectSetFiboDescription( "XIT_FIBO", 7,fiboValue127+" --> 127.0%");
      ObjectSetFiboDescription( "XIT_FIBO", 8,fiboValue162+" --> 162.0%");
   }
}

void notifyOutside(){
   BuildInterface(0);
   bool brokeLevel = false;
   ArrayFill(OutSideNotificationBuffer,0,ArraySize(FibPriceLevelsRetracement),-1);
   //Só me interesso pelos níveis de 0.628 e 0.786 que são os índices 4 e 5 do array FibPriceLevelsRetracement
   for(int i = 4;i<ArraySize(FibPriceLevelsRetracement);i++){
      if(isHightoLow){
         //Preço tocou ou cruzou o nível de Fib atual
         if(FibPriceLevelsRetracement[i]<=iHigh(Symbol(),PERIOD_CURRENT,1)){
            //Fechamento menor que a abertura
            if(iClose(Symbol(),PERIOD_CURRENT,1) < iOpen(Symbol(),PERIOD_CURRENT,1)){
               //Fechamento menor que o nível Fib
               if(iClose(Symbol(),PERIOD_CURRENT,1) < FibPriceLevelsRetracement[i]){
                  OutSideNotificationBuffer[0] = iLow(Symbol(),PERIOD_CURRENT,1);
                  brokeLevel = true;
                  break;
               }
            }
         }else
	 //Preço tocou ou cruzou o nível de Fib atual
         if(FibPriceLevelsRetracement[i]>=iLow(Symbol(),PERIOD_CURRENT,1)){
            //Fechamento menor que a abertura
            if(iClose(Symbol(),PERIOD_CURRENT,1) > iOpen(Symbol(),PERIOD_CURRENT,1)){
               //Fechamento maior que o nível Fib
               if(iClose(Symbol(),PERIOD_CURRENT,1) > FibPriceLevelsRetracement[i]){
                  OutSideNotificationBuffer[0] = iHigh(Symbol(),PERIOD_CURRENT,1);
                  brokeLevel = true;
                  break;
               }
            }
         }
      }
   }
   if(brokeLevel) BuildInterface(OutSideNotificationBuffer[0]);
}

void BuildInterface(double PriceThatCrosses)
{
   if (hwnd>0){
      guiRemoveAll(hwnd);
      guiCleanup(hwnd);
   }
   // Build Options Panel
   // Build a panel
   Label1  = guiAdd(hwnd,"label",GUIX,30,200,40,"Indicator Data:");
   Label2  = guiAdd(hwnd,"label",GUIX,50,200,40,"Price that crosses: " + DoubleToString(PriceThatCrosses,Digits));
   guiSetBgColor(hwnd,Label1,RoyalBlue);
   guiSetTextColor(hwnd,Label1,White);
   guiSetBorderColor(hwnd,Label1,clrRed);
 
} 
Razão: