FiboRetracement3

Download script
Author: Copyright � 2005, MetaQuotes Software Corp.
FiboRetracement3

This script is an automated technical analysis tool designed for the MetaTrader 4 platform. Its primary purpose is to identify significant price structural points—specifically high and low "fractals"—and use those points to automatically draw Fibonacci Retracement levels on a trading chart.

Core Logic Overview

The script operates by scanning historical price data to establish a dynamic range of market activity. Rather than simply looking at the most recent price, it seeks out "turning points" where the market has established a clear local peak or valley.

1. Fractal Identification (The Foundation)

The tool looks for Fractals, which are specific price points that stand out relative to their neighbors. To do this, the script uses three main settings:

  • Left and Right Parameters: These define how many candles to the left and right of a point must be lower (for a high) or higher (for a low) for that point to be considered a significant "peak" or "valley."
  • Filter: This acts as a sensitivity buffer, ensuring that small price fluctuations don't trigger a new level, helping to keep the analysis focused on meaningful trends.

2. Dynamic Range Detection

Once the script identifies these high and low fractal points, it calculates the overall market range. It specifically seeks out the "extremes" within a certain distance of the current price. This allows the tool to distinguish between an old historical move and the current active price structure.

3. Automated Fibonacci Drawing

The most distinctive feature of this script is its ability to automatically generate two separate Fibonacci Retracement objects:

  • Primary Retracement: It identifies the most recent significant high and low points within the active range. It then draws a Fibonacci tool connecting these two points. This helps traders visualize potential support and resistance levels based on the current "swing" of the market.
  • Secondary Retracement: The script takes it a step further by attempting to identify a secondary trend structure. It looks for a subsequent high or low point (depending on the direction of the primary move) to draw a second Fibonacci tool. This provides a deeper look at multi-wave price action, showing how the market might be consolidating or moving into a larger trend.

4. Visual Representation

To assist with readability, the script calculates several intermediate levels between the high and low points (calculated as specific fractions like 1/6, 1/3, 1/2, 2/3, and 5/6). While it primarily focuses on the full Fibonacci structures, these calculations ensure the visual representation is mathematically consistent with standard trading retracement theories.

Summary for the User

In simple terms, this script removes the manual work of "eye-balling" the chart to find where a trend started and ended. It automatically scans the recent history, finds the most important peaks and valleys based on your preferred sensitivity, and draws the Fibonacci lines for you. This allows you to see potential reversal zones and targets instantly as the market evolves.

Miscellaneous
Implements a curve of type %1
10 Views
0 Downloads
0 Favorites
FiboRetracement3
//+------------------------------------------------------------------+
//|                                              FiboRetracement.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, 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_LEVELCOLOR, DodgerBlue);
      ObjectSet(fibo,OBJPROP_LEVELSTYLE,STYLE_DOT);
      ObjectSet(fibo,OBJPROP_LEVELWIDTH,1);
      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_LEVELCOLOR,Gray);
      ObjectSet(fibo2,OBJPROP_LEVELSTYLE,STYLE_DOT);
      ObjectSet(fibo2,OBJPROP_LEVELWIDTH,1);
      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