rvmFractalsLevel
Download scriptThis script is designed to analyze market price action by identifying significant structural points (fractals) and automatically projecting Fibonacci-based levels and fans onto the trading chart. Below is a professional breakdown of how the logic functions for a non-technical user:
Core Market Structure Analysis
The primary goal of the script is to distinguish between "noise" and meaningful price movements. It achieves this by identifying Fractals, which are local highs and lows within a specific window of time (defined by your left and right settings).
- Upper Levels: The script scans for significant peaks. It doesn't just take every high point; it looks for a peak that stands out relative to the candles surrounding it.
- Lower Levels: Similarly, it scans for significant troughs or "floors" in the price action.
- Dynamic Updates: As new price data arrives, the script continuously evaluates whether the current price is breaking through these established levels or if a new dominant high/low has formed to reset the boundaries.
Smart Level Filtering
One of the sophisticated aspects of this logic is how it handles "sticky" price levels. Instead of creating a cluttered chart with every minor fluctuation:
- Persistence: Once a significant level is identified, the script "holds" that price level until the market provides enough evidence to break out of it.
- Sensitivity Filter: It includes a customizable filter that allows you to determine how much "breathing room" is needed before the script acknowledges a price move as a legitimate break or a new level.
Automated Fibonacci Projection
Beyond just identifying highs and lows, the script automatically performs geometric analysis to draw Fibonacci Fans.
- Pivot Identification: The logic searches for the most recent significant structural shift (the "swing"). It looks back through the history of identified levels to find the definitive start and end points of the current trend.
- Fan Construction: Using these pivot points, it automatically draws two different Fibonacci Fans:
- Primary Fan: Projects a series of diagonal lines based on the most recent major move.
- Secondary Fan: Projects a secondary set of lines to help identify deeper trend exhaustion or acceleration.
- Real-time Adjustment: Because the script is dynamic, these fans will automatically shift and reposition themselves as the market creates new fractals, ensuring that the technical analysis always reflects the current market structure.
Visual Data Layers
In addition to the primary price levels and Fibonacci Fans, the logic calculates and prepares several internal "stages." These are essentially mathematical subdivisions between the highest and lowest identified points. While these act as the engine for the script's calculations, they ensure that the visible lines on your chart remain mathematically consistent with the overall market range.
Summary of User Experience
For a trader, this means the script does the heavy lifting of "chart reading." It automatically finds the most important highs and lows, draws the trend boundaries, and plots the Fibonacci projection lines without requiring you to manually click points on the screen. It provides a clean, automated view of where market support and resistance currently sit based on historical fractal behavior.
//+------------------------------------------------------------------+
//| rvmFractalsLevel.mq4 |
//| Copyright © 2005, Profi_R |
//| rvm_fam@fromru.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, Profi_R"
#property link "rvm_fam@fromru.com"
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_color1 DeepSkyBlue
#property indicator_color2 DeepSkyBlue
#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_FIBOFAN,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_FIBOFAN,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