FiboRetracement3D
Download scriptThis script is designed to automatically identify key market structure points and project Fibonacci retracement levels onto a trading chart. It works by dynamically scanning price history to find significant "peaks" (highs) and "troughs" (lows), which it uses as the foundation for its visual analysis.
Core Logic and Behavior
1. Identification of Key Price Points (Fractals) The script begins by searching for specific structural points in the market. Rather than just looking at every candle, it identifies "Fractals"—these are local highs or lows that stand out relative to the candles immediately surrounding them.
- It looks back and forward across a user-defined range of candles to confirm if a high point is truly a peak or if a low point is a significant trough.
- The script uses a "filtering" mechanism to ensure it isn't distracted by minor price noise, focusing only on the most prominent structural shifts.
2. Dynamic Range Mapping Once the script identifies these primary peaks and troughs, it establishes a "channel."
- Upper Level: It tracks the highest point of the current trend. If a new peak is formed, it updates the level; if price stays below that peak, it maintains the existing level.
- Lower Level: Similarly, it tracks the lowest point of the current move, updating as the market reaches new lows.
- The logic includes an intelligent "buffer" to decide when a price movement is significant enough to be considered a new structural level versus just a temporary fluctuation.
3. Fibonacci Calculations Based on the established upper and lower levels, the script automatically calculates several intermediate price points. It generates specific percentage-based markers (like 1/6th, 1/3rd, 1/2, 2/3rds, and 5/6ths of the range). These represent potential areas of support or resistance where price might react during a retracement.
4. Automated Drawing and Projection The final stage of the logic is the visual representation on your chart:
- Primary Fibonacci: The script identifies the most recent significant price swing (the distance between two major peaks or troughs) and draws a primary Fibonacci tool to visualize the current move.
- Secondary Projection: It performs an additional calculation to find a secondary, extended Fibonacci zone. This helps traders see further "echoes" of the market structure beyond the immediate price action.
- Auto-Cleanup: The script is designed to manage its own visual objects, ensuring that when you remove the indicator, the drawings are cleared from your chart to keep your workspace clean.
Summary for the User
In simple terms, this tool acts as an automated "scout." It looks at the history of the market to find out where the most important highs and lows occurred, draws a line showing the current range between them, and then places Fibonacci levels on that range to help you identify where the price might stall or reverse.
//+------------------------------------------------------------------+
//| 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 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