FiboRetracement3D_v1
Download scriptThis 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.
//+------------------------------------------------------------------+
//| 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