FiboRetracement3_003

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

This script is designed for the MetaTrader 4 platform to automatically identify key price structural points and project Fibonacci retracement levels directly onto your trading chart. Instead of requiring the user to manually click on highs and lows, the logic automates the detection of "fractals"—significant peaks and valleys in price action—to determine where the market's primary trends and corrections are occurring.

Core Logic Overview

The script operates through three distinct phases: structural detection, dynamic level calculation, and automated drawing.

1. Structural Identification (Fractal Detection)

The tool scans historical price data to find local maxima (peaks) and local minima (valleys). It uses a "look-around" logic based on user-defined parameters (nLeft, nRight). This means a peak is only confirmed if it is higher than all surrounding candles within a specific window. By doing this, the script ignores minor price "noise" and focuses on significant structural turning points.

2. Dynamic Support and Resistance Tracking

Once the peaks and valleys are identified, the script continuously monitors the current price movement relative to these levels:

  • Upper Boundaries: It tracks the highest confirmed peak. If the price moves above a previous level but doesn't form a new fractal, it maintains the existing structural level.
  • Lower Boundaries: Similarly, it tracks the lowest confirmed valley.
  • Filtering: A built-in filter allows the script to be more or less sensitive to price fluctuations, ensuring that minor movements don't prematurely trigger a change in the identified structural boundaries.

3. Fibonacci Projection and Auto-Drawing

The most advanced part of the logic involves calculating the distance between the most recent significant peak and valley:

  • Automatic Scaling: The script calculates the "swing" (the range between the current high and low). It then automatically generates several price levels based on common mathematical proportions (such as 1/6, 1/3, 1/2, 2/3, and 5/6 of the range).
  • Smart Object Creation: The script identifies the most relevant start and end points for a Fibonacci retracement. It dynamically creates and updates two distinct Fibonacci objects on your chart:
    • Primary Fibo: Projects from the primary swing high to the low (or vice versa).
    • Secondary Fibo: Identifies subsequent structural shifts to provide a deeper look at potential trend exhaustion or continuation points.

Summary of User Experience

For a non-programmer, this tool acts as an automated analyst. It scans the "history" of the chart to find where the market actually turned, then draws the mathematical retracement zones for you. As new price data arrives, the script updates these lines in real-time, moving the Fibonacci levels automatically as the market creates new significant highs and lows.

Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
FiboRetracement3_003
//+------------------------------------------------------------------+
//|                                              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_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