FiboRetracement3D_v1

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

This script is designed to automatically identify significant price結構 and draw Fibonacci retracement levels on a trading chart. Rather than relying on manual drawing, the logic automates the detection of "fractals"—which are essentially local peaks (highs) and valleys (lows) in price action—to determine where major trend movements began and ended.

Core Logic Overview

1. Identification of Structural Highs and Lows The script scans historical price data to find prominent "fractals." It looks for specific candles where the high or low is significantly higher or lower than the surrounding bars (based on a user-defined range). These points serve as the primary anchors for the trend.

2. Dynamic Support and Resistance Tracking The script maintains two continuous buffers:

  • Up Channel: Tracks the "ceiling" or upper boundary of the price movement.
  • Down Channel: Tracks the "floor" or lower boundary of the price movement.

It uses a filtering mechanism to decide when these levels should update. If a new fractal is formed that exceeds the previous level, the script updates the boundary. If the price stays within a certain range, it holds the previous level steady, helping to smooth out minor market "noise."

3. Fibonacci Level Calculation Once the primary upper and lower boundaries are established, the script calculates several intermediate levels between them (specifically at 20%, 33%, 50%, 66%, and 83% intervals). These represent potential areas of support or resistance where the price might pull back or stall.

4. Automated Fibonacci Drawing The most distinct feature of this script is its ability to automatically place two Fibonacci objects on the chart:

  • Primary Retracement: It identifies the most recent major high and low and draws a standard Fibonacci retracement tool between them.
  • Secondary Retracement: The logic goes further by identifying a secondary "swing" point (the next significant peak or valley) to draw a second, nested Fibonacci tool. This allows traders to see multiple layers of potential retracement zones simultaneously.

User-Adjustable Logic Parameters

The behavior of the script can be modified through four main inputs:

  • TimeFrame: Determines the period of the candles used for analysis.
  • nLeft & nRight: Defines how many bars to the left and right of a candle must be "lower" or "higher" for it to be considered a valid fractal (peak/valley).
  • Filter: A sensitivity setting that determines how much "breathing room" the price needs before the script recognizes it has broken out of a current level.

Summary of Behavior

Essentially, this tool acts as an automated analyst. It watches the market history to find where the "big moves" happened, identifies the high and low points of those moves, and then automatically paints Fibonacci retracement zones on your chart. This helps in identifying where price might find balance after a significant move without requiring the user to manually click and drag tools onto the screen.

Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each barSeries array that contains close prices for each barSeries array that contains open prices of each bar
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
FiboRetracement3D_v1
//+------------------------------------------------------------------+
//|                                              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 Magenta
#property indicator_color2 Magenta
#property indicator_color3 Magenta
#property indicator_color4 Magenta
#property indicator_color5 Magenta
#property indicator_color6 Magenta
#property indicator_color7 Magenta
#property indicator_color8 Magenta
//---- input parameters
extern int TimeFrame=60;
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[];

string fibo,fibo2;

//----
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);

   fibo="Fibo "+TimeFrame;
   fibo2="Fibo2 "+TimeFrame;

//---- 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=iBars(NULL,TimeFrame)-1-nLeft;n>=nRight;n--)
   {
      //âåðõíèå ôðàêòàëû
      //åñëè íà÷àëî îòðèñîâêè âåðõíåãî óðîâíÿ íå îïðåäåëåíî
      if(draw_begin1==0)
      {
      //òåêóùàÿ ñâå÷à ìàêñèìóì íà ëîêàëüíîì ïðîìåæóòêå?
      if(iHigh(NULL,TimeFrame,n)>=iLow(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,Range,n-nRight)))
      {
         int fRange=nvnLeft(n,nLeft)+nvnRight(n,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(iHigh(NULL,TimeFrame,n)>=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,fRange,n-nvnRight(n,nRight))))
         {
            draw_begin1=iBars(NULL,TimeFrame)-n;//íà÷àëî îòðèñîâêè âåðõíåãî óðîâíÿ îïðåäåëåíî
            for(i=iBars(NULL,TimeFrame)-1;i>draw_begin1;i--)
            {
               UpBuffer[i]=iHigh(NULL,TimeFrame,iBars(NULL,TimeFrame)-draw_begin1);
            }
         }
      }//êîíåö äåéñòâèé åñëè if(iHigh(NULL,TimeFrame,n)>=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,Range,n-nRight))=èñòèíà
      }//êîíåö óñëîâèÿ if(draw_begin1==0)
      
      //íèæíèå ôðàêòàëû
      //åñëè íà÷àëî îòðèñîâêè íèæíåãî óðîâíÿ íå îïðåäåëåíî
      if(draw_begin2==0)
      {
      //òåêóùàÿ ñâå÷à ìèíèìóì íà ëîêàëüíîì ïðîìåæóòêå?
      if(iLow(NULL,TimeFrame,n)<=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,Range,n-nRight)))
      {
         fRange=nvnLeft(n,nLeft)+nvnRight(n,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(iLow(NULL,TimeFrame,n)<=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_HIGH,fRange,n-nvnRight(n,nRight)))) 
         {
            draw_begin2=iBars(NULL,TimeFrame)-n;//íà÷àëî îòðèñîâêè íèæíåãî óðîâíÿ îïðåäåëåíî
            for(i=iBars(NULL,TimeFrame)-1;i>draw_begin2;i--)
            {
               DnBuffer[i]=iLow(NULL,TimeFrame,iBars(NULL,TimeFrame)-draw_begin2);
            }
         }
      }//êîíåö óñëîâèÿ if(iLow(NULL,TimeFrame,n)<=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,Range,n-nRight)))=true
      }//êîíåö óñëîâèÿ if(draw_begin2==0)
      
      //åñëè îáà íà÷àëà îòðèñîâêè óðîâíåé îïðåäåëåíû, âûõîäèì èç öèêëà for(n=iBars(NULL,TimeFrame)-1-nLeft;n>=nRight;n--)
      if(draw_begin1>0&&draw_begin2>0) break;
   }//êîíåö öèêëà for(n=iBars(NULL,TimeFrame)-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();
//---- 
   //ïåðåáèðàåì ñâå÷êè îò (iBars(NULL,TimeFrame)-counted_iBars(NULL,TimeFrame)-nLeft) äî (nRight) âêëþ÷èòåëüíî
   for(i=iBars(NULL,TimeFrame)-1-counted_bars-nLeft;i>=nRight;i--)
   {
      //åñëè ñâå÷à ëîêàëüíûé ìàêñèìóì
      if(iHigh(NULL,TimeFrame,i)>=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,Range,i-nRight)))
      {
         //Print(TimeToStr(iTime(NULL,TimeFrame,i)), "******Ëîêàëüíûé ìàêñèìóì");
         fRange=nvnLeft(i,nLeft)+nvnRight(i,nRight)+1;
         //åñëè îíà æå - ôðàêòàë
         if(iHigh(NULL,TimeFrame,i)>=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,fRange,i-nvnRight(i,nRight))))
         {
            UpStage=iHigh(NULL,TimeFrame,i);
            //Print("    îíà æå ôðàêòàë");
         }
         else
         {
            if(iHigh(NULL,TimeFrame,i)<=UpBuffer[i+1])
            {
               UpStage=UpBuffer[i+1];
               //Print("    íå ôðàêòàë, íî íèæå ïðåäûäóùåãî óðîâíÿ");
            }
            else
            {
               UpStage=nfUp(i);
               //Print("    íå ôðàêòàë, âûøå ïðåäûäóùåãî óðîâíÿ");
            }
         }
      }
      else
      {
         //Print(TimeToStr(iTime(NULL,TimeFrame,i)), "******íå ëîêàëüíûé ìàêñèìóì");
         if(iHigh(NULL,TimeFrame,i)<=UpBuffer[i+1])
         {
            UpStage=UpBuffer[i+1];
            //Print("    íèæå ïðåäûäóùåãî óðîâíÿ");
         }
         else
         {
            UpStage=nfUp(i);
            //Print("    âûøå ïðåäûäóùåãî óðîâíÿ");
         }
      }
      
      //åñëè ñâå÷à ëîêàëüíûé ìèíèìóì
      if(iLow(NULL,TimeFrame,i)<=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,Range,i-nRight)))
      {
         fRange=nvnLeft(i,nLeft)+nvnRight(i,nRight)+1;
         //Print(TimeToStr(iTime(NULL,TimeFrame,i))," ",nvnLeft(i,nLeft)," ",nvnRight(i,nRight)+1);
         //åñëè îíà æå - ôðàêòàë
         if(iLow(NULL,TimeFrame,i)<=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_HIGH,fRange,i-nvnRight(i,nRight)))) 
         {
            DnStage=iLow(NULL,TimeFrame,i);
         }
         else
         {
            if(iLow(NULL,TimeFrame,i)>=DnBuffer[i+1])
            {
               DnStage=DnBuffer[i+1];
            }
            else
            {
               DnStage=nfDn(i);
            }
         }
      }
      else
      {
         if(iLow(NULL,TimeFrame,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=iBars(NULL,TimeFrame)-counted_bars-nLeft;i>=nRight;i--)
   for(i=nRight-1;i>=0;i--)
   {
      if(iHigh(NULL,TimeFrame,i)<=UpBuffer[i+1])
      {
         UpStage=UpBuffer[i+1];
      }
      else
      {
         UpStage=nfUp(i);
      }
      if(iLow(NULL,TimeFrame,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;
   LastDn=DnBuffer[0];
   for(cb=1;cb<=iBars(NULL,TimeFrame)-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<=iBars(NULL,TimeFrame)-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=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,MathMax(dn_x,up_x),0));
   st_l=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,MathMax(dn_x,up_x),0));
   //y1=MathMin(iOpen(NULL,TimeFrame,x1),)x1));
   //y1=MathMax(iClose(NULL,TimeFrame,x1),iClose(NULL,TimeFrame,x1));
   for(cb=MathMax(dn_x,up_x)-1;cb>=0;cb--)
   {
      if(iHigh(NULL,TimeFrame,cb)==st_h || iLow(NULL,TimeFrame,cb)==st_l)
      {
         if(iHigh(NULL,TimeFrame,cb)==st_h && (x1==0 || x2==0) )
         {
            if(x1==0)
            {
               x1=cb;
               y1=iHigh(NULL,TimeFrame,x1);
               continue;
            }
            else
            {
               x2=cb;
               y2=iHigh(NULL,TimeFrame,x2);
               break;
            }
         }
         else
         {
            if(x1==0)
            {
               x1=cb;
               y1=iLow(NULL,TimeFrame,x1);
               continue;
            }
            else
            {
               x2=cb;
               y2=iLow(NULL,TimeFrame,x2);
               break;
            }
         }
      }
   }
   //Print("x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2);
   if( ObjectFind(fibo)!=-1 )
   {
      ObjectSet(fibo,OBJPROP_TIME1,iTime(NULL,TimeFrame,x1));
      ObjectSet(fibo,OBJPROP_PRICE1,y1);
      ObjectSet(fibo,OBJPROP_TIME2,iTime(NULL,TimeFrame,x2));
      ObjectSet(fibo,OBJPROP_PRICE2,y2);
   }
   else
   {
      ObjectCreate(fibo,OBJ_FIBO,0,iTime(NULL,TimeFrame,x1),y1,iTime(NULL,TimeFrame,x2),y2);
      ObjectSet(fibo,OBJPROP_COLOR,DodgerBlue);
      ObjectSet(fibo,OBJPROP_STYLE,STYLE_DOT);
   }
//----- à ýòî îòðèñîâêà âñïîìîãàòåëüíîãî âååðà ôèáîíà÷÷è
   if(y2>y1)
   {
      st_3=iLow(NULL,TimeFrame,Lowest(NULL,TimeFrame,MODE_LOW,x2,0));
   }
   else
   {
      st_3=iHigh(NULL,TimeFrame,Highest(NULL,TimeFrame,MODE_HIGH,x2,0));
   }

   for(cb=0;cb<x2;cb++)
   {
      if(y2>y1 && iLow(NULL,TimeFrame,cb)==st_3)
      {
         x3=cb;
         y3=iLow(NULL,TimeFrame,cb);
         break;
      }
      else
      {
         if(y2<y1 && iHigh(NULL,TimeFrame,cb)==st_3)
         {
            x3=cb;
            y3=iHigh(NULL,TimeFrame,cb);
            break;
         }
      }
   }
   if( ObjectFind(fibo2)!=-1 )
   {
      ObjectSet(fibo2,OBJPROP_TIME1,iTime(NULL,TimeFrame,x2));
      ObjectSet(fibo2,OBJPROP_PRICE1,y2);
      ObjectSet(fibo2,OBJPROP_TIME2,iTime(NULL,TimeFrame,x3));
      ObjectSet(fibo2,OBJPROP_PRICE2,y3);
   }
   else
   {
      ObjectCreate(fibo2,OBJ_FIBO,0,iTime(NULL,TimeFrame,x2),y2,iTime(NULL,TimeFrame,x3),y3);
      ObjectSet(fibo2,OBJPROP_COLOR,Yellow);
      ObjectSet(fibo2,OBJPROP_STYLE,STYLE_DOT);
   }

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


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(iClose(NULL,TimeFrame,i)<=UpBuffer[l]+(UpBuffer[l]-DnBuffer[l])*filter/100)
         {
            Price=UpBuffer[l];
            flag=1;
            //Print(TimeToStr(iTime(NULL,TimeFrame,i))," ",l," ",Bars," ",Price," ",UpBuffer[l));
         }
      }
      else
      {
         if(iHigh(NULL,TimeFrame,i)<=UpBuffer[l])
         {
            Price=UpBuffer[l];
            flag=1;
         }
      }
      if(Price>0) break;
   }

   if(flag==0) Price=iHigh(NULL,TimeFrame,i);

   return(Price);

}


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(iClose(NULL,TimeFrame,i)>=DnBuffer[l]-(UpBuffer[l]-DnBuffer[l])*filter/100)
         {
            Price=DnBuffer[l];
            flag=1;
         }
      }
      else
      {
         if(iLow(NULL,TimeFrame,i)>=DnBuffer[l])
         {
            Price=DnBuffer[l];
            flag=1;
         }
      }
      if(Price>0) break;
   }

   if(flag==0) Price=iLow(NULL,TimeFrame,i);

   return(Price);

}



int nvnLeft(int i,int n)
{
   int k=0,l;
   for(l=i+1;l<=iBars(NULL,TimeFrame)-1;l++)
   {
      if(iHigh(NULL,TimeFrame,l)<iHigh(NULL,TimeFrame,l+1)&&iLow(NULL,TimeFrame,l)>iLow(NULL,TimeFrame,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(iHigh(NULL,TimeFrame,l)<iHigh(NULL,TimeFrame,l+1)&&iLow(NULL,TimeFrame,l)>iOpen(NULL,TimeFrame,l+1)) continue;
      k++;
      if(k==n)
      {
         k=i-l;
         break;
      }
   }

   return(k);

}



int deinit()
{
   ObjectDelete(fibo);
   ObjectDelete(fibo2);
   return(0);
}


Comments