olyakish_fractals_04
Download scriptThis script is a specialized technical analysis tool designed for the MetaTrader platform. It identifies specific price patterns known as "Fractals" and categorizes them based on market dynamics like volume and momentum to help traders visualize trend strength.
Core Functionality
The primary purpose of this tool is to filter out standard fractal points and highlight only those that meet specific criteria involving volume and a custom momentum calculation (referred to in the code as MFI). Instead of showing every minor price peak or valley, it classifies identified fractals into four distinct categories:
- Green Fractal: Indicates a high-momentum move supported by significant trading volume.
- Red Fractal: Indicates a high-momentum move where momentum is decreasing despite high volume.
- Blue Fractal: Indicates a low-volume move where momentum is still increasing.
- Saddle Brown Fractal: Indicates a low-volume move where both volume and momentum are decreasing.
How the Logic Works
The script performs a sophisticated "look-back" analysis to determine these categories:
- Fractal Identification: The tool scans the price history to find upper and lower fractal points (peaks and valleys).
- Comparative Analysis: When it finds a current fractal, it automatically searches back through the chart history to find the previous opposite fractal (e.g., if it finds a peak, it looks for the preceding valley).
- Volume and Momentum Calculation: For both the current and previous points, the script calculates:
- The total trading volume over a specific range of bars.
- A momentum value derived from price movement relative to that volume.
- Categorization: It compares the current point against the previous one using a user-defined percentage (the "Percent" setting). Based on whether the volume increased or decreased and whether the momentum is rising or falling, it assigns one of the four colors mentioned above.
Dynamic Visual Aids
In addition to identifying these colored fractal points on the chart, the script includes several visual enhancements:
- Trend Lines: The tool automatically draws trend lines based on the "Alligator" indicator. These lines are used to confirm price action; the script specifically looks for fractals that occur outside of the Alligator's "jaws," "teeth," and "lips."
- Historical Reference: There is an option to display "Old Lines," which allows traders to see previous trend levels as dashed lines, providing a visual history of where price trends have shifted.
- Automatic Updates: The script constantly updates these lines and points in real-time as new price data becomes available, ensuring the visual representation remains current with the market's movement.
//+------------------------------------------------------------------+
//| v04 |
//| |
//| v02 |
//| Äîáàâëåí ïðîöåíò äëÿ îòñåèâàíèÿ ôðàêòàëîâ |
//| v03 |
//| Ðèñóåò ëèíèè |
//| v04 |
//| Ôèëüòð äëÿ ëèíèé ïî àëëèãàòîðó |
//+------------------------------------------------------------------+
#property copyright "olyakish"
#property link ""
//----
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Lime //Çåëåíûé ôðàêòàë
#property indicator_color2 Red // Ïðèñåäàþùèé
#property indicator_color3 SaddleBrown //Óâÿäàþùèé
#property indicator_color4 Blue // Ôàëüøèâûé
//----
extern int Pips = 15;
extern int ShiftBars = 250;
extern string rem1="Ïðîöåíò äëÿ îòñåèâàíèÿ ïî îáúåìó";
extern int Percent=110;
extern string rem2="Ðèñîâàòü ïðåäûäóùèå ëèíèè?";
extern bool UseOldLine=true;
double ExtLimeBuffer[];
double ExtRedBuffer[];
double ExtSaddleBrownBuffer[];
double ExtBlueBuffer[];
int i,j;
double a_Fractal[2]; // 0- ïîñëåäíèé 1-ïðåäûäóùèé
double a_MFI[2]; // 0- ïîñëåäíèé 1-ïðåäûäóùèé
double a_Volume[2]; // 0- ïîñëåäíèé 1-ïðåäûäóùèé
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
SetIndexShift(0,0);
SetIndexShift(1,0);
SetIndexShift(2,0);
SetIndexShift(3,0);
//----
SetIndexBuffer(0, ExtLimeBuffer);
SetIndexBuffer(1, ExtRedBuffer);
SetIndexBuffer(2, ExtSaddleBrownBuffer);
SetIndexBuffer(3, ExtBlueBuffer);
//----
SetIndexStyle(0, DRAW_ARROW );
SetIndexStyle(1, DRAW_ARROW);
SetIndexStyle(2, DRAW_ARROW);
SetIndexStyle(3, DRAW_ARROW);
SetIndexArrow(0,177);
SetIndexArrow(1,177);
SetIndexArrow(2,177);
SetIndexArrow(3,177);
///----
SetIndexLabel(0, "Çåëåíûé ôðàêòàë");
SetIndexLabel(1, "Ïðèñåäàþùèé ôðàêòàë");
SetIndexLabel(2, "Óâÿäàþùèé ôðàêòàë");
SetIndexLabel(3, "Ôàëüøèâûé ôðàêòàë");
//----
ObjectCreate("Up",OBJ_TREND,0,iTime(NULL, 0, 2),High[2],iTime(NULL, 0, 1),High[1],0,0);
ObjectSet("Up",OBJPROP_COLOR,Aqua);
ObjectSet("Up",OBJPROP_RAY,true);
ObjectSet("Up",OBJPROP_BACK,1);
ObjectCreate("Down",OBJ_TREND,0,iTime(NULL, 0, 2),Low[2],iTime(NULL, 0, 1),Low[1],0,0);
ObjectSet("Down",OBJPROP_COLOR,Tomato);
ObjectSet("Down",OBJPROP_RAY,true);
ObjectSet("Down",OBJPROP_BACK,1);
if (UseOldLine)
{
ObjectCreate("Up_Prev",OBJ_TREND,0,iTime(NULL, 0, 2),High[2],iTime(NULL, 0, 1),High[1],0,0);
ObjectSet("Up_Prev",OBJPROP_COLOR,Aqua);
ObjectSet("Up_Prev",OBJPROP_RAY,true);
ObjectSet("Up_Prev",OBJPROP_STYLE,STYLE_DASH);
ObjectSet("Up_Prev",OBJPROP_BACK,1);
ObjectCreate("Down_Prev",OBJ_TREND,0,iTime(NULL, 0, 2),Low[2],iTime(NULL, 0, 1),Low[1],0,0);
ObjectSet("Down_Prev",OBJPROP_COLOR,Tomato);
ObjectSet("Down_Prev",OBJPROP_RAY,true);
ObjectSet("Down_Prev",OBJPROP_STYLE,STYLE_DASH);
ObjectSet("Down_Prev",OBJPROP_BACK,1);
}
//----
return(0);
}
int deinit()
{
ObjectDelete("Up");
ObjectDelete("Down");
if (UseOldLine)
{
ObjectDelete("Up_Prev");
ObjectDelete("Down_Prev");
}
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
int n=3;
while (ExtLimeBuffer[n]!=NULL || ExtRedBuffer[n]!=NULL || ExtSaddleBrownBuffer[n]!=NULL || ExtBlueBuffer[n]!=NULL)
{
if (n>ShiftBars) {n=ShiftBars;break;}
n++;
}
for(int i=n+20; i>=3; i--)
{
//-- âåðõíèå ôðàêòàëû
ArrayInitialize(a_Fractal,0);
ArrayInitialize(a_MFI,0);
ArrayInitialize(a_Volume,0);
if (iFractals(NULL,0,MODE_UPPER,i)!=0) // íà i áàðå åñòü ôðàêòàë ââåðõ
{
a_Fractal[0]=iFractals(NULL,0,MODE_UPPER,i); // öåíà íà ôðàêòàëå
a_Volume[0]=Volume[i]+Volume[i+1]+Volume[i+2]+Volume[i-1]+Volume[i-2]; // îáúåì
a_MFI[0]=(High[i]-Low[i]+High[i-1]-Low[i-1]+High[i-2]-Low[i-2]+High[i+1]-Low[i+1]+High[i+2]-Low[i+2])/a_Volume[0]; // MFI
// ïîøëè èñêàòü ôðàêòàë íà âíèç ïî èñòîðèè
j=i+1;
while (a_Fractal[1]==0 && j<Bars)
{
if (iFractals(NULL,0,MODE_UPPER,j)!=0) {break;}
if (iFractals(NULL,0,MODE_LOWER,j)!=0) //-- Íàøëè ôðàêòàë âíèç
{
a_Fractal[1]=iFractals(NULL,0,MODE_LOWER,j);
a_Volume[1]=Volume[j+2]+Volume[j+1]+Volume[j]+Volume[j-1]+Volume[j-2];
a_MFI[1]=(High[j+1]-Low[j+1]+High[j+2]-Low[j+2]+High[j]-Low[j]+High[j-1]-Low[j-1]+High[j-2]-Low[j-2])/a_Volume[1];
if (a_Volume[0]>a_Volume[1]*Percent/100 && a_MFI[0]<a_MFI[1]){ExtRedBuffer[i]=High[i]+Pips*Point;break;} // èìååì ïðèñåäàþùèé ôðàêòàë (MFI - îáúåì +)
if (a_Volume[0]>a_Volume[1]*Percent/100 && a_MFI[0]>a_MFI[1]){ExtLimeBuffer[i]=High[i]+Pips*Point;break;} // èìååì çåëåíûé ôðàêòàë (MFI + îáúåì +)
if (a_Volume[0]*Percent/100<a_Volume[1] && a_MFI[0]>a_MFI[1]){ExtBlueBuffer[i]=High[i]+Pips*Point;break;} // èìååì ôàëüøèâûé ôðàêòàë (MFI + îáúåì -)
if (a_Volume[0]*Percent/100<a_Volume[1] && a_MFI[0]<a_MFI[1]){ExtSaddleBrownBuffer[i]=High[i]+Pips*Point;break;} // èìååì óâÿäàþùèé ôðàêòàë (MFI - îáúåì -)
}
j++;
}
}
//--- íèæíèå ôðàêòàëû
ArrayInitialize(a_Fractal,0);
ArrayInitialize(a_MFI,0);
ArrayInitialize(a_Volume,0);
if (iFractals(NULL,0,MODE_LOWER,i)!=0) // íà i áàðå åñòü ôðàêòàë âíèç
{
a_Fractal[0]=iFractals(NULL,0,MODE_LOWER,i); // öåíà íà ôðàêòàëå
a_Volume[0]=Volume[i]+Volume[i+1]+Volume[i+2]+Volume[i-1]+Volume[i-2]; // îáúåì
a_MFI[0]=(High[i]-Low[i]+High[i-1]-Low[i-1]+High[i-2]-Low[i-2]+High[i+1]-Low[i+1]+High[i+2]-Low[i+2])/a_Volume[0]; // MFI
// ïîøëè èñêàòü ôðàêòàë íà ââåðõ ïî èñòîðèè
j=i+1;
while (a_Fractal[1]==0 && j<Bars)
{
if (iFractals(NULL,0,MODE_LOWER,j)!=0) {break;}
if (iFractals(NULL,0,MODE_UPPER,j)!=0) //-- Íàøëè ôðàêòàë ââåðõ
{
a_Fractal[1]=iFractals(NULL,0,MODE_UPPER,j);
a_Volume[1]=Volume[j+2]+Volume[j+1]+Volume[j]+Volume[j-1]+Volume[j-2];
a_MFI[1]=(High[j+1]-Low[j+1]+High[j+2]-Low[j+2]+High[j]-Low[j]+High[j-1]-Low[j-1]+High[j-2]-Low[j-2])/a_Volume[1];
if (a_Volume[0]>a_Volume[1]*Percent/100 && a_MFI[0]<a_MFI[1]){ExtRedBuffer[i]=Low[i]-Pips*Point;break;} // èìååì ïðèñåäàþùèé ôðàêòàë (MFI - îáúåì +)
if (a_Volume[0]>a_Volume[1]*Percent/100 && a_MFI[0]>a_MFI[1]){ExtLimeBuffer[i]=Low[i]-Pips*Point;break;} // èìååì çåëåíûé ôðàêòàë (MFI + îáúåì +)
if (a_Volume[0]*Percent/100<a_Volume[1] && a_MFI[0]>a_MFI[1]){ExtBlueBuffer[i]=Low[i]-Pips*Point;break;} // èìååì ôàëüøèâûé ôðàêòàë (MFI + îáúåì -)
if (a_Volume[0]*Percent/100<a_Volume[1] && a_MFI[0]<a_MFI[1]){ExtSaddleBrownBuffer[i]=Low[i]-Pips*Point;break;} // èìååì óâÿäàþùèé ôðàêòàë (MFI - îáúåì -)
}
j++;
}
}
}
/// îòðèñîâêà ëèíèé
double _Price[3,2];
int _Time[3,2];
ArrayInitialize(_Price,-1);
ArrayInitialize(_Time,-1);
int up=0,down=0;
for(i=3; i<=300; i++)
{
//up
double iLips=iAlligator(NULL, 0, 13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN, MODE_GATORLIPS, i);
double iTeeth=iAlligator(NULL, 0, 13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN, MODE_GATORTEETH, i);
double iJaw=iAlligator(NULL, 0, 13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN, MODE_GATORJAW, i);
if (ExtRedBuffer[i]!=2147483647 && iFractals(NULL,0,MODE_UPPER,i)!=NULL && up<=2 && iFractals(NULL,0,MODE_UPPER,i)<=ExtRedBuffer[i]
&& iFractals(NULL,0,MODE_UPPER,i)>iLips && iFractals(NULL,0,MODE_UPPER,i)>iTeeth && iFractals(NULL,0,MODE_UPPER,i)>iJaw)
{
_Price[up,0]=ExtRedBuffer[i];_Time[up,0]=iTime(NULL, 0, i);up++;
}
if (ExtRedBuffer[i]!=2147483647 && iFractals(NULL,0,MODE_LOWER,i)!=0 && down<=2 && iFractals(NULL,0,MODE_LOWER,i)>=ExtRedBuffer[i]
&& iFractals(NULL,0,MODE_LOWER,i)<iLips && iFractals(NULL,0,MODE_LOWER,i)<iTeeth && iFractals(NULL,0,MODE_LOWER,i)<iJaw)
{
_Price[down,1]=ExtRedBuffer[i];_Time[down,1]=iTime(NULL, 0, i);down++;
}
}
ObjectMove("Up",1,_Time[0,0],_Price[0,0]);
ObjectMove("Up",0,_Time[1,0],_Price[1,0]);
ObjectMove("Down",1,_Time[0,1],_Price[0,1]);
ObjectMove("Down",0,_Time[1,1],_Price[1,1]);
if (UseOldLine)
{
ObjectMove("Up_Prev",1,_Time[1,0],_Price[1,0]);
ObjectMove("Up_Prev",0,_Time[2,0],_Price[2,0]);
ObjectMove("Down_Prev",1,_Time[1,1],_Price[1,1]);
ObjectMove("Down_Prev",0,_Time[2,1],_Price[2,1]);
}
return(0);
}
//+------------------------------------------------------------------+
Comments