FiboRetracement3_v2

Author: Copyright � 2005, MetaQuotes Software Corp.
FiboRetracement3_v2

This script is designed to automatically identify significant price structure points on a trading chart and project Fibonacci retracement levels based on those movements. Instead of requiring a user to manually click on highs and lows, the logic automates the detection of market "fractals"—the peaks and valleys that define the current trend.

Core Logic Overview

1. Dynamic Peak and Valley Detection The script scans historical price data to identify local maximums (peaks) and minimums (valleys). It uses a user-defined lookback and lookforward range (set by the nLeft and nRight parameters) to ensure that a high or low is only considered significant if it stands out compared to the surrounding candles. By checking these neighbors, the script filters out "market noise" and focuses on major structural turning points.

2. Intelligent Level Tracking The script maintains two primary tracking boundaries:

  • Upper Channel: Tracks the most recent significant highs.
  • Lower Channel: Tracks the most recent significant lows.

As new price data arrives, the logic evaluates whether a new peak/valley has been formed. If the price breaks beyond the existing tracked level in a way that meets the "fractal" criteria, the script updates the boundaries. If the price stays within the current range but moves lower than the previous high (or higher than the previous low), it maintains the integrity of the current structural levels.

3. Automated Fibonacci Mapping Once the significant peaks and valleys are identified, the script performs several automated calculations:

  • Primary Retracement: It identifies a primary trend move and automatically draws a Fibonacci object from the start of that move to its peak/valley.
  • Secondary Retracement: It then searches for a secondary price movement to draw a second Fibonacci object. This helps traders visualize multiple layers of retracement or "waves" within a single market cycle.

4. Mathematical Projections Beyond the standard levels, the script calculates several intermediate price points between the upper and lower channels. These are calculated using fractional divisions (such as 1/2, 1/3, 2/3, 5/6, etc.) to provide a granular view of where price might react within a specific trading range.

Summary for the User

Essentially, this tool acts as an automated "chart artist." It watches the market to find where the trend changed last, marks those points automatically, and draws Fibonacci retracement lines and intermediate support/resistance levels based on those findings. This allows a trader to see potential price targets and areas of interest without having to manually measure every move on the screen.

Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
FiboRetracement3_v2
//+------------------------------------------------------------------+
//|                                              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 Red
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Blue
#property indicator_color5 Red
#property indicator_color6 Blue
#property indicator_color7 Red
#property indicator_color8 Blue
//---- 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
   SetIndexStyle(0, DRAW_LINE, 0, 2);
   SetIndexStyle(1, DRAW_LINE, 0, 2);
   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_LEVELCOLOR, Green);       
       ObjectSet(fibo, OBJPROP_STYLE, STYLE_DOT);
//       ObjectSet(fibo, OBJPROP_LEVELSTYLE, STYLE_DASHDOT);       
     }
//----- à ýòî îòðèñîâêà âñïîìîãàòåëüíîãî âååðà ôèáîíà÷÷è
   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_LEVELCOLOR, Brown);  
       ObjectSet(fibo2, OBJPROP_STYLE, STYLE_DOT);
//       ObjectSet(fibo2, OBJPROP_LEVELSTYLE, STYLE_DASHDOT);  
     }
//----
   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);
  }
//+------------------------------------------------------------------+
//| Ôóíêöèÿ nvnLeft âîçâðàùàåò äëÿ ïåðåäàííîé åé ñâå÷è ìèíèìàëüíîå   |
//| êîëè÷åñòâî ñâå÷åé ñëåâà, âêëþ÷àÿ "âíóòðåííèå", äëÿ òîãî, ÷òîáû   |
//| ÷èñëî íå âíóòðåííèõ ñâå÷åé â ïîëó÷åííîì äèàïàçîíå áûëî íå ìåíüøå,| 
//| ÷åì óêàçàíî âî âòîðîì ïàðàìåòðå.                                 |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Ôóíêöèÿ nvnRight âîçâðàùàåò äëÿ ïåðåäàííîé åé ñâå÷è ìèíèìàëüíîå  |
//| êîëè÷åñòâî ñâå÷åé ñïðàâà, âêëþ÷àÿ "âíóòðåííèå", äëÿ òîãî, ÷òîáû  |
//| ÷èñëî íå âíóòðåííèõ ñâå÷åé â ïîëó÷åííîì äèàïàçîíå áûëî íå ìåíüøå,| 
//| ÷åì óêàçàíî âî âòîðîì ïàðàìåòðå.                                 |                                   |
//+------------------------------------------------------------------+
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