FIBONACCI RETRACMENT

Download script
Author: Copyright � 2006, MetaQuotes Software Corp.
FIBONACCI RETRACMENT

This script is designed to automatically identify significant price movements on a trading chart and project Fibonacci retracement levels based on those movements. Instead of requiring a user to manually click and select high and low points, the logic uses mathematical filters to "scan" the history of the candles to find the most relevant structural pivots.

Core Logic Overview

1. Structural Pivot Identification The script begins by scanning the price history to identify "Fractals"—these are significant local peaks (highs) and valleys (lows). It doesn't just look at every candle; it uses specific parameters (nLeft, nRight, and filter) to ensure that a peak or valley is actually significant relative to the candles surrounding it. This helps filter out minor market "noise" and focuses on major price swings.

2. Dynamic Boundary Tracking Once the script identifies a major high and a major low, it establishes "Upper" and "Lower" boundary levels. The logic is designed to track these levels dynamically:

  • If the price creates a new, higher peak or a lower valley that meets the fractal criteria, the script updates the boundaries.
  • If the price stays within the current range, the script maintains the existing levels.
  • It uses a "filter" mechanism to provide a small buffer zone, ensuring that tiny fluctuations don't cause the levels to jump erratically.

3. Automated Fibonacci Projection After identifying the most recent significant high and low points, the script automatically calculates and draws two distinct Fibonacci retracement zones:

  • Primary Retracement: It identifies the most recent major swing and draws a standard Fibonacci level based on that movement.
  • Secondary/Extended Retracement: The logic performs an additional calculation to find an extended point of interest, creating a second, secondary Fibonacci zone. This helps traders visualize different depths of potential pullbacks.

4. Visual Output The script handles all the drawing on the chart automatically:

  • It draws the primary Fibonacci level in DodgerBlue with a dotted style.
  • It draws the secondary Fibonacci level in Yellow with a dotted style.
  • It also calculates intermediate price levels (based on divisions like 1/3, 1/2, 2/3, and 5/6 of the current range) to provide a comprehensive view of potential support and resistance zones.

Summary for the User

Essentially, this tool acts as an automated "technical analyst." It looks back at the market history, identifies the most important price swings (ignoring the small wobbles), and automatically draws the Fibonacci retracement levels for you. As new significant highs or lows are formed, the script adjusts these lines to reflect the newest market structure.

Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
FIBONACCI RETRACMENT
//+------------------------------------------------------------------+
//|                                         FIBONACCI RETRACMENT.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 Black
#property indicator_color2 Black
#property indicator_color3 Black
#property indicator_color4 Black
#property indicator_color5 Black
#property indicator_color6 Black
#property indicator_color7 Black
#property indicator_color8 Black
//---- input parameters
extern int nLeft=50;
extern int nRight=50;
extern int filter=10;
//---- buffers
double UpBuffer[];
double DnBuffer[];
double f_2[];
double f_3[];
double f_4[];
double f_5[];
double f_6[];

//----
int draw_begin1=0, draw_begin2=0, d_b3=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   double nfUp;
//---- indicators
   IndicatorBuffers(8);
   SetIndexStyle(0,DRAW_LINE,0,3);
   SetIndexStyle(1,DRAW_LINE,0,3);
   SetIndexStyle(2,DRAW_LINE,2);
   SetIndexStyle(3,DRAW_LINE,2);
   SetIndexStyle(4,DRAW_LINE,2);
   SetIndexStyle(5,DRAW_LINE,2);
   SetIndexStyle(6,DRAW_LINE,2);
   SetIndexBuffer(0,UpBuffer);
   SetIndexBuffer(1,DnBuffer);
   SetIndexBuffer(2,f_2);
   SetIndexBuffer(3,f_3);
   SetIndexBuffer(4,f_4);
   SetIndexBuffer(5,f_5);
   SetIndexBuffer(6,f_6);

//---- name for DataWindow and indicator subwindow label
   string short_name; //îáÿâëåíèå ïåðåìåííîé short_name òèïà "ñòðîêîâûé"
   //ïåðåìåííîé short_name ïðèñâàèâàåì ñòðîêîâîå çíà÷åíèå ðàâíîå âûðàæåíèþ
   short_name="rvmFractalsLevel("+nLeft+","+nRight+","+filter+")"; 
   IndicatorShortName(short_name); //äëÿ îòîáðàæåíèÿ íà ãðàôèêå ïðèñâîèì èíäèêàòîðó êðàòêîå
                                   //íàèìåíîâàíèå
   //äëÿ îòîáðàæåíèÿ íà ãðàôèêå ïðèñâîèì ìåòêå îòîáðàæàþùåé çíà÷åíèÿ 0 áóôåðà èìÿ Up Channel
   SetIndexLabel(0,"Up Level ("+nLeft+","+nRight+","+filter+")");
   //äëÿ îòîáðàæåíèÿ íà ãðàôèêå ïðèñâîèì ìåòêå îòîáðàæàþùåé çíà÷åíèÿ 1 áóôåðà èìÿ Down Channel
   SetIndexLabel(1,"Down Level ("+nLeft+","+nRight+","+filter+")");
   SetIndexLabel(2,"f_2 ("+nLeft+","+nRight+","+filter+")");
   SetIndexLabel(3,"f_3 ("+nLeft+","+nRight+","+filter+")");
   SetIndexLabel(4,"f_4 ("+nLeft+","+nRight+","+filter+")");
   SetIndexLabel(5,"f_5 ("+nLeft+","+nRight+","+filter+")");
   SetIndexLabel(6,"f_6 ("+nLeft+","+nRight+","+filter+")");

//---- Çäåñü îïðåäåëèì íà÷àëüíûå òî÷êè äëÿ ïðîðèñîâêè èíäèêàòîðà
   int n,k,i,Range=nLeft+nRight+1;
   //ïåðåáåðåì ñâå÷êè îò (âñåãî ñâå÷åê ìèíóñ ìèíèìóì ñâå÷åê ñëåâà) äî (ìèíèìóì ñâå÷åê ñïðàâà)
   for(n=Bars-1-nLeft;n>=nRight;n--)
   {
      //âåðõíèå ôðàêòàëû
      //åñëè íà÷àëî îòðèñîâêè âåðõíåãî óðîâíÿ íå îïðåäåëåíî
      if(draw_begin1==0)
      {
      //òåêóùàÿ ñâå÷à ìàêñèìóì íà ëîêàëüíîì ïðîìåæóòêå?
      if(High[n]>=High[Highest(NULL,0,MODE_HIGH,Range,n-nRight)])
      {
         int fRange=nvnLeft(n,nLeft)+nvnRight(n,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(High[n]>=High[Highest(NULL,0,MODE_HIGH,fRange,n-nvnRight(n,nRight))])
         {
            draw_begin1=Bars-n;//íà÷àëî îòðèñîâêè âåðõíåãî óðîâíÿ îïðåäåëåíî
            for(i=Bars-1;i>draw_begin1;i--)
            {
               UpBuffer[i]=High[Bars-draw_begin1];
            }
         }
      }//êîíåö äåéñòâèé åñëè if(High[n]>=High[Highest(NULL,0,MODE_HIGH,Range,n-nRight)]=èñòèíà
      }//êîíåö óñëîâèÿ if(draw_begin1==0)
      
      //íèæíèå ôðàêòàëû
      //åñëè íà÷àëî îòðèñîâêè íèæíåãî óðîâíÿ íå îïðåäåëåíî
      if(draw_begin2==0)
      {
      //òåêóùàÿ ñâå÷à ìèíèìóì íà ëîêàëüíîì ïðîìåæóòêå?
      if(Low[n]<=Low[Lowest(NULL,0,MODE_LOW,Range,n-nRight)])
      {
         fRange=nvnLeft(n,nLeft)+nvnRight(n,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(Low[n]<=Low[Lowest(NULL,0,MODE_HIGH,fRange,n-nvnRight(n,nRight))]) 
         {
            draw_begin2=Bars-n;//íà÷àëî îòðèñîâêè íèæíåãî óðîâíÿ îïðåäåëåíî
            for(i=Bars-1;i>draw_begin2;i--)
            {
               DnBuffer[i]=Low[Bars-draw_begin2];
            }
         }
      }//êîíåö óñëîâèÿ if(Low[n]<=Low[Lowest(NULL,0,MODE_LOW,Range,n-nRight)])=true
      }//êîíåö óñëîâèÿ if(draw_begin2==0)
      
      //åñëè îáà íà÷àëà îòðèñîâêè óðîâíåé îïðåäåëåíû, âûõîäèì èç öèêëà for(n=Bars-1-nLeft;n>=nRight;n--)
      if(draw_begin1>0&&draw_begin2>0) break;
   }//êîíåö öèêëà for(n=Bars-1-nLeft;n>=nRight;n--)
//----
   if(draw_begin1>draw_begin2)
   {
      d_b3=draw_begin1;
   }
   else
   {
      d_b3=draw_begin2;
   }
   SetIndexDrawBegin(0,draw_begin1); //óñòàíîâêà íà÷àëüíîé òî÷êè ïðîðèñîâêè äëÿ 0 áóôåðà
   SetIndexDrawBegin(1,draw_begin2); //óñòàíîâêà íà÷àëüíîé òî÷êè ïðîðèñîâêè äëÿ 1 áóôåðà
   SetIndexDrawBegin(2,d_b3);
   SetIndexDrawBegin(3,d_b3);
   SetIndexDrawBegin(4,d_b3);
   SetIndexDrawBegin(5,d_b3);
   SetIndexDrawBegin(6,d_b3);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double UpStage=0.0,DnStage=0.0;
   int i,j,fRange,Range=nLeft+nRight+1;
   int counted_bars=IndicatorCounted();
//---- 
   //ïåðåáèðàåì ñâå÷êè îò (Bars-counted_bars-nLeft) äî (nRight) âêëþ÷èòåëüíî
   for(i=Bars-1-counted_bars-nLeft;i>=nRight;i--)
   {
      //åñëè ñâå÷à ëîêàëüíûé ìàêñèìóì
      if(High[i]>=High[Highest(NULL,0,MODE_HIGH,Range,i-nRight)])
      {
         //Print(TimeToStr(Time[i]), "******Ëîêàëüíûé ìàêñèìóì");
         fRange=nvnLeft(i,nLeft)+nvnRight(i,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(High[i]>=High[Highest(NULL,0,MODE_HIGH,fRange,i-nvnRight(i,nRight))])
         {
            UpStage=High[i];
            //Print("    îíà æå ôðàêòàë");
         }
         else
         {
            if(High[i]<=UpBuffer[i+1])
            {
               UpStage=UpBuffer[i+1];
               //Print("    íå ôðàêòàë, íî íèæå ïðåäûäóùåãî óðîâíÿ");
            }
            else
            {
               UpStage=nfUp(i);
               //Print("    íå ôðàêòàë, âûøå ïðåäûäóùåãî óðîâíÿ");
            }
         }
      }
      else
      {
         //Print(TimeToStr(Time[i]), "******íå ëîêàëüíûé ìàêñèìóì");
         if(High[i]<=UpBuffer[i+1])
         {
            UpStage=UpBuffer[i+1];
            //Print("    íèæå ïðåäûäóùåãî óðîâíÿ");
         }
         else
         {
            UpStage=nfUp(i);
            //Print("    âûøå ïðåäûäóùåãî óðîâíÿ");
         }
      }
      
      //åñëè ñâå÷à ëîêàëüíûé ìèíèìóì
      if(Low[i]<=Low[Lowest(NULL,0,MODE_LOW,Range,i-nRight)])
      {
         fRange=nvnLeft(i,nLeft)+nvnRight(i,nRight)+1;
         //Print(TimeToStr(Time[i])," ",nvnLeft(i,nLeft)," ",nvnRight(i,nRight)+1);
         //åñëè îíà æå - ôðàêòàë
         if(Low[i]<=Low[Lowest(NULL,0,MODE_HIGH,fRange,i-nvnRight(i,nRight))]) 
         {
            DnStage=Low[i];
         }
         else
         {
            if(Low[i]>=DnBuffer[i+1])
            {
               DnStage=DnBuffer[i+1];
            }
            else
            {
               DnStage=nfDn(i);
            }
         }
      }
      else
      {
         if(Low[i]>=DnBuffer[i+1])
         {
            DnStage=DnBuffer[i+1];
         }
         else
         {
            DnStage=nfDn(i);
         }
      }
      UpBuffer[i]=UpStage;
      DnBuffer[i]=DnStage;
//---- ðàñ÷åò îñòàëüíûõ áóôåðîâ
      f_2[i]=NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/6,4);
      f_3[i]=NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/3,4);
      f_4[i]=NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/2,4);
      f_5[i]=NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])*2/3,4);
      f_6[i]=NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])*5/6,4);

   }//êîíåö öèêëà for(i=Bars-counted_bars-nLeft;i>=nRight;i--)
   for(i=nRight-1;i>=0;i--)
   {
      if(High[i]<=UpBuffer[i+1])
      {
         UpStage=UpBuffer[i+1];
      }
      else
      {
         UpStage=nfUp(i);
      }
      if(Low[i]>=DnBuffer[i+1])
      {
         DnStage=DnBuffer[i+1];
      }
      else
      {
         DnStage=nfDn(i);
      }
      UpBuffer[i]=UpStage;
      DnBuffer[i]=DnStage;
//---- ðàñ÷åò îñòàëüíûõ áóôåðîâ
      f_2[i] =NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/6,4);
      f_3[i] =NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/3,4);
      f_4[i] =NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])/2,4);
      f_5[i] =NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])*2/3,4);
      f_6[i] =NormalizeDouble(DnBuffer[i]+(UpBuffer[i]-DnBuffer[i])*5/6,4);

   }
//---- ïîñòðîåíèå âååðà Ôèáîíà÷÷è
   double LastUp, LastDn, st_h, st_l, st_3, y1, y2, y3;
   int tmp, x1=0, x2=0, x3=0, cb, dn_x, up_x;
   string fibo="Fibo 1", fibo2="Fibo 2";
   LastDn=DnBuffer[0];
   for(cb=1;cb<=Bars-1;cb++)
   {
      if(tmp!=1 && LastDn>DnBuffer[cb])
      {
         tmp=1;
         continue;
      }
      if(tmp==1 && DnBuffer[cb]>DnBuffer[cb-1])
      {
         tmp=0;
         dn_x=cb-1;
         break;
      }
   }
   LastUp=UpBuffer[0];
   for(cb=1;cb<=Bars-1;cb++)
   {
      if(tmp!=1 && LastUp<UpBuffer[cb])
      {
         tmp=1;
         continue;
      }
      if(tmp==1 && UpBuffer[cb]<UpBuffer[cb-1])
      {
         tmp=0;
         up_x=cb-1;
         break;
      }
   }
   st_h=High[Highest(NULL,0,MODE_HIGH,MathMax(dn_x,up_x),0)];
   st_l=Low[Lowest(NULL,0,MODE_LOW,MathMax(dn_x,up_x),0)];
   //y1=MathMin(Open[x1],Close[x1]);
   //y1=MathMax(Open[x1],Close[x1]);
   for(cb=MathMax(dn_x,up_x)-1;cb>=0;cb--)
   {
      if(High[cb]==st_h || Low[cb]==st_l)
      {
         if(High[cb]==st_h && (x1==0 || x2==0) )
         {
            if(x1==0)
            {
               x1=cb;
               y1=High[x1];
               continue;
            }
            else
            {
               x2=cb;
               y2=High[x2];
               break;
            }
         }
         else
         {
            if(x1==0)
            {
               x1=cb;
               y1=Low[x1];
               continue;
            }
            else
            {
               x2=cb;
               y2=Low[x2];
               break;
            }
         }
      }
   }
   //Print("x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2);
   if( ObjectFind(fibo)!=-1 )
   {
      ObjectSet(fibo,OBJPROP_TIME1,Time[x1]);
      ObjectSet(fibo,OBJPROP_PRICE1,y1);
      ObjectSet(fibo,OBJPROP_TIME2,Time[x2]);
      ObjectSet(fibo,OBJPROP_PRICE2,y2);
   }
   else
   {
      ObjectCreate(fibo,OBJ_FIBO,0,Time[x1],y1,Time[x2],y2);
      ObjectSet(fibo,OBJPROP_COLOR,DodgerBlue);
      ObjectSet(fibo,OBJPROP_STYLE,STYLE_DOT);
   }
//----- à ýòî îòðèñîâêà âñïîìîãàòåëüíîãî âååðà ôèáîíà÷÷è
   if(y2>y1)
   {
      st_3=Low[Lowest(NULL,0,MODE_LOW,x2,0)];
   }
   else
   {
      st_3=High[Highest(NULL,0,MODE_HIGH,x2,0)];
   }

   for(cb=0;cb<x2;cb++)
   {
      if(y2>y1 && Low[cb]==st_3)
      {
         x3=cb;
         y3=Low[cb];
         break;
      }
      else
      {
         if(y2<y1 && High[cb]==st_3)
         {
            x3=cb;
            y3=High[cb];
            break;
         }
      }
   }
   if( ObjectFind(fibo2)!=-1 )
   {
      ObjectSet(fibo2,OBJPROP_TIME1,Time[x2]);
      ObjectSet(fibo2,OBJPROP_PRICE1,y2);
      ObjectSet(fibo2,OBJPROP_TIME2,Time[x3]);
      ObjectSet(fibo2,OBJPROP_PRICE2,y3);
   }
   else
   {
      ObjectCreate(fibo2,OBJ_FIBO,0,Time[x2],y2,Time[x3],y3);
      ObjectSet(fibo2,OBJPROP_COLOR,Yellow);
      ObjectSet(fibo2,OBJPROP_STYLE,STYLE_DOT);
   }

//----
   return(0);
}
//+------------------------------------------------------------------+

//****************************************************************************//
// Ôóíêöèÿ nfUp âîçâðàùàåò áëèæàéøåå ñëåâà ê ïåðåäàííîé ñâå÷å çíà÷åíèå áóôåðà //
// èíäèêàòîðà, áîëüøåå èëè ðàâíîå çíà÷åíèþ High(Close) äëÿ ïåðåäàííîé ñâå÷è   //
//****************************************************************************//
double nfUp(int i)
   {
   int l,flag=0;
   double Price=0.0;
//----------
   for(l=i+1;l<Bars-draw_begin1-1;l++)
   {
      if(filter>0)
      {
         if(Close[i]<=UpBuffer[l]+(UpBuffer[l]-DnBuffer[l])*filter/100)
         {
            Price=UpBuffer[l];
            flag=1;
            //Print(TimeToStr(Time[i])," ",l," ",Bars," ",Price," ",UpBuffer[l]);
         }
      }
      else
      {
         if(High[i]<=UpBuffer[l])
         {
            Price=UpBuffer[l];
            flag=1;
         }
      }
      if(Price>0) break;
   }
   if(flag==0) Price=High[i];
//----------
   return(Price);
   }
//+------------------------------------------------------------------+

//****************************************************************************//
// Ôóíêöèÿ nfDn âîçâðàùàåò áëèæàéøåå ñëåâà ê ïåðåäàííîé ñâå÷å çíà÷åíèå áóôåðà //
// èíäèêàòîðà, ìåíüøåå èëè ðàâíîå çíà÷åíèþ Low(Close) äëÿ ïåðåäàííîé ñâå÷è    //
//****************************************************************************//
double nfDn(int i)
   {
   int l,flag=0;
   double Price=0.0;
//----------
   for(l=i+1;l<Bars-draw_begin2-1;l++)
   {
      if(filter>0)
      {
         if(Close[i]>=DnBuffer[l]-(UpBuffer[l]-DnBuffer[l])*filter/100)
         {
            Price=DnBuffer[l];
            flag=1;
         }
      }
      else
      {
         if(Low[i]>=DnBuffer[l])
         {
            Price=DnBuffer[l];
            flag=1;
         }
      }
      if(Price>0) break;
   }
   if(flag==0) Price=Low[i];
//----------
   return(Price);
   }
//+------------------------------------------------------------------+

//*****************************************************************************************//
// Ôóíêöèÿ âîçâðàùàåò äëÿ ïåðåäàííîé åé ñâå÷è, ìèíèìàëüíîå êîëè÷åñòâî ñâå÷åé ñëåâà         //
// âêëþ÷àÿ "âíóòðåííèå", äëÿ òîãî, ÷òîáû ÷èñëî íå âíóòðåííèõ ñâå÷åé â ïîëó÷åííîì äèàïàçîíå //
// áûëî íå ìåíüøå, ÷åì óêàçàíî âî âòîðîì ïàðàìåòðå                                         //
//*****************************************************************************************//
int nvnLeft(int i,int n)
   {
   int k=0,l;
   for(l=i+1;l<=Bars-1;l++)
   {
      if(High[l]<High[l+1]&&Low[l]>Low[l+1]) continue;
      k++;
      if(k==n)
      {
         k=l-i;
         break;
      }
   }
//----------
   return(k);
   }
//+------------------------------------------------------------------+

//*****************************************************************************************//
// Ôóíêöèÿ âîçâðàùàåò äëÿ ïåðåäàííîé åé ñâå÷è, ìèíèìàëüíîå êîëè÷åñòâî ñâå÷åé ñïðàâà        //
// âêëþ÷àÿ "âíóòðåííèå", äëÿ òîãî, ÷òîáû ÷èñëî íå âíóòðåííèõ ñâå÷åé â ïîëó÷åííîì äèàïàçîíå //
// áûëî íå ìåíüøå, ÷åì óêàçàíî âî âòîðîì ïàðàìåòðå                                         //
//*****************************************************************************************//
int nvnRight(int i,int n)
   {
   int k=0,l;
   for(l=i-1;l>=0;l--)
   {
      if(High[l]<High[l+1]&&Low[l]>Low[l+1]) continue;
      k++;
      if(k==n)
      {
         k=i-l;
         break;
      }
   }
//----------
   return(k);
   }

//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
   string fibo="Fibo 1", fibo2="Fibo 2";
   ObjectDelete(fibo);
   ObjectDelete(fibo2);
//----
   return(0);
  }

Comments