Gartley Reversal Auto
Download scriptThis script is a specialized technical analysis tool designed to automatically identify and project specific price patterns on a trading chart. It focuses on detecting "Gartley" formations—a type of harmonic pattern used by traders to predict where the market might reverse direction based on previous price swings.
Core Functionality
The script works by monitoring significant price peaks and valleys (highs and lows) in real-time. It uses a mathematical backbone known as a "ZigZag" to filter out minor market noise, allowing it to focus only on the most important structural movements of the price.
How the Logic Works:
- Pattern Recognition: The script scans historical price data to identify a sequence of key points (labeled internally as A, B, C, D, and X). It looks for a specific geometric relationship between these points that defines a potential reversal zone.
- Dynamic Calculation: Once the script identifies these structural points, it performs several automatic calculations:
- Reversal Ranges: It calculates specific boundaries (Min and Max) where the price is statistically likely to react or "bounce."
- Projected Targets: Based on the proportions of the current pattern, it automatically calculates three different potential profit targets. These are projected forward based on the previous legs of the move.
- Visual Feedback: Instead of requiring the user to do any manual math, the script draws these levels directly onto the trading chart as horizontal lines.
- Red Lines represent the identified reversal boundaries.
- Blue, Green, and Yellow Dots/Lines represent different projected reversal points based on various mathematical ratios (such as the 1.618 Fibonacci ratio).
- Goldenrod (Gold) Lines highlight the primary profit targets.
- Real-Time Updates: As new price data comes in, the script continuously recalculates these positions. This means the lines on your chart will move and update dynamically to stay accurate with the current market action.
- Data Overlay: For advanced users, the script provides a text summary in the corner of the screen. This shows the exact percentage "retracements" of the price action, allowing you to see exactly how much the market has pulled back relative to its previous move.
User Experience Summary
From a user's perspective, this tool removes the manual labor of identifying harmonic patterns. By simply running the script, the chart becomes populated with automated "zones" and "targets." This allows a trader to see at a glance where the "rules" of the current price pattern suggest the market should stop moving and potentially head in the opposite direction.
//+------------------------------------------------------------------+
//| Gartley Reversal Auto.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//| http://forum.fxexpert.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link "http://forum.fxexpert.ru"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Yellow
extern int BarsCount=300;
extern int depth=16;
extern int deviation=5;
extern int backstep=3;
extern int maf=1;
extern int info=0;
extern int FontSize=8;
extern int DeleteType=0; /*0-delete all objects, 1-keet all*, 2-keep targets, 3-keep targets and reverses*/
double PointX=0;
double PointA=0;
double PointB=0;
double PointC=0;
double PointD=0;
double ReversalRangeMax=0;
double ReversalRangeMin=0;
double D_Revers1=0;
double D_Revers3=0;
double D_Revers2=0;
double Target1=0;
double Target3=0;
double Target2=0;
double zz=0;
double zzp=0;
int shift=0, Bars_=200, k=0, cnt=0;
bool ft=true;
bool ftp=true;
double RevPoint[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
//IndicatorBuffers(1);
SetIndexStyle(0,DRAW_ARROW,EMPTY,EMPTY,Yellow);
SetIndexArrow(0, 159);
SetIndexBuffer(0,RevPoint);
SetIndexLabel(0, "ZigZagE");
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
if (DeleteType==0)
{
ObjectDelete("D_Revers1");
ObjectDelete("D_Revers2");
ObjectDelete("D_Revers3");
ObjectDelete("D_Revers1_txt");
ObjectDelete("D_Revers2_txt");
ObjectDelete("D_Revers3_txt");
ObjectDelete("ReversalRangeMax");
ObjectDelete("ReversalRangeMin");
ObjectDelete("ReversalRangeMax_txt");
ObjectDelete("ReversalRangeMin_txt");
ObjectDelete("Target1");
ObjectDelete("Target2");
ObjectDelete("Target3");
ObjectDelete("Target1_txt");
ObjectDelete("Target2_txt");
ObjectDelete("Target3_txt");
}
if (DeleteType==2)
{
ObjectDelete("D_Revers1");
ObjectDelete("D_Revers2");
ObjectDelete("D_Revers3");
ObjectDelete("D_Revers1_txt");
ObjectDelete("D_Revers2_txt");
ObjectDelete("D_Revers3_txt");
ObjectDelete("ReversalRangeMax");
ObjectDelete("ReversalRangeMin");
ObjectDelete("ReversalRangeMax_txt");
ObjectDelete("ReversalRangeMin_txt");
}
if (DeleteType==3)
{
ObjectDelete("D_Revers1");
ObjectDelete("D_Revers2");
ObjectDelete("D_Revers3");
ObjectDelete("D_Revers1_txt");
ObjectDelete("D_Revers2_txt");
ObjectDelete("D_Revers3_txt");
}
//----
Comment("");
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
//----
int counted_bars=IndicatorCounted();
int limit; // îãðàíè÷èòåëü ðàñ÷åòîâ
//----
if (counted_bars==0) limit=Bars-1; // ïîñ÷èòàííûõ áàðîâ åùå íåò, áóäåò ñ÷èòàòü ñ ñàìîãî íà÷àëà
if (counted_bars>0) limit=Bars-counted_bars-1; // âû÷òåì èç ÷èñëà äîñòóïíûõ áàðîâ êîëè÷åñòâî
//ïîñ÷èòàííûõ áàðîâ è óìåíüøèì íà åäèíèöó
if (ftp) {Comment(" "); ftp=false; }
for(shift=limit; shift>0; shift--)
{
if (maf==0) {PointX=0;}
zz=iCustom(NULL, 0, "ZigZag",depth,deviation,backstep,0,shift);
if ((ft) || (zz!=0))
{
k=0;
for(cnt = shift; cnt<BarsCount; cnt++)
{
zzp=iCustom(NULL, 0, "ZigZagE",depth,deviation,backstep,0,cnt);
if ((zzp!=0) && (k==4) && (maf==1)) {PointX=zzp;RevPoint[cnt]=zzp;break;}
if ((zzp!=0) && (k==3)) {k=k+1;PointA=zzp;RevPoint[cnt]=zzp;}
if ((zzp!=0) && (k==2)) {k=k+1;PointB=zzp;RevPoint[cnt]=zzp;}
if ((zzp!=0) && (k==1)) {k=k+1;PointC=zzp;RevPoint[cnt]=zzp;}
if ((zzp!=0) && (k==0)) {k=k+1;PointD=zzp;RevPoint[cnt]=zzp;}
}
}
}
ReversalRangeMax=NormalizeDouble(PointA+(PointX-PointA)*0.786,4);
ReversalRangeMin=NormalizeDouble(PointA+(PointX-PointA)*0.618,4);
D_Revers1=NormalizeDouble(PointC+(PointB-PointA),4);
D_Revers3=NormalizeDouble(PointC+(PointB-PointC)*1.618,4);
D_Revers2=NormalizeDouble(PointC+(PointB-PointC)*1.272,4);
Target1=NormalizeDouble(PointD-(PointD-PointC)*0.618,4);
Target3=PointD-(PointB-PointC);
Target2=NormalizeDouble(PointD-(PointD-PointC)*0.786,4);
if ((zz!=0) || (ft))
{
if (ObjectFind("ReversalRangeMax") != 0)
{
ObjectCreate("ReversalRangeMax",OBJ_HLINE,0,Time[25],ReversalRangeMax,Time[1],ReversalRangeMax);
ObjectCreate("ReversalRangeMax_txt",OBJ_TEXT,0,Time[40],ReversalRangeMax,Time[1],ReversalRangeMax);
ObjectSet("ReversalRangeMax",OBJPROP_COLOR,Red);
ObjectSet("ReversalRangeMax",OBJPROP_WIDTH,1);
ObjectSet("ReversalRangeMax",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText("ReversalRangeMax_txt", "ReversalRangeMax "+DoubleToStr(ReversalRangeMax,4), FontSize, "Tahoma", Red);
}
else
{
ObjectMove("ReversalRangeMax", 0,Time[1],ReversalRangeMax);
ObjectMove("ReversalRangeMax_txt", 0,Time[40],ReversalRangeMax);
}
if (ObjectFind("ReversalRangeMin") != 0)
{
ObjectCreate("ReversalRangeMin",OBJ_HLINE,0,Time[25],ReversalRangeMin,Time[1],ReversalRangeMin);
ObjectCreate("ReversalRangeMin_txt",OBJ_TEXT,0,Time[40],ReversalRangeMin,Time[1],ReversalRangeMin);
ObjectSet("ReversalRangeMin",OBJPROP_COLOR,Red);
ObjectSet("ReversalRangeMin",OBJPROP_WIDTH,1);
ObjectSet("ReversalRangeMin",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText("ReversalRangeMin_txt", "ReversalRangeMin "+DoubleToStr(ReversalRangeMin,4), FontSize, "Tahoma", Red);
}
else
{
ObjectMove("ReversalRangeMin", 0,Time[1],ReversalRangeMin);
ObjectMove("ReversalRangeMin_txt", 0,Time[40],ReversalRangeMin);
}
if (ObjectFind("D_Revers1") != 0)
{
ObjectCreate("D_Revers1",OBJ_HLINE,0,Time[25],D_Revers1,Time[1],D_Revers1);
ObjectCreate("D_Revers1_txt",OBJ_TEXT,0,Time[25],D_Revers1,Time[1],D_Revers1);
ObjectSet("D_Revers1",OBJPROP_COLOR,Blue);
ObjectSet("D_Revers1",OBJPROP_WIDTH,1);
ObjectSet("D_Revers1",OBJPROP_STYLE,STYLE_DOT);
ObjectSetText("D_Revers1_txt", "D_Revers1 "+DoubleToStr(D_Revers1,4), FontSize, "Tahoma", Blue);
}
else
{
ObjectMove("D_Revers1", 0,Time[1],D_Revers1);
ObjectMove("D_Revers1_txt", 0,Time[25],D_Revers1);
}
if (ObjectFind("D_Revers2") != 0)
{
ObjectCreate("D_Revers2",OBJ_HLINE,0,Time[25],D_Revers2,Time[1],D_Revers2);
ObjectCreate("D_Revers2_txt",OBJ_TEXT,0,Time[25],D_Revers2,Time[1],D_Revers2);
ObjectSet("D_Revers2",OBJPROP_COLOR,LimeGreen);
ObjectSet("D_Revers2",OBJPROP_WIDTH,1);
ObjectSet("D_Revers2",OBJPROP_STYLE,STYLE_DOT);
ObjectSetText("D_Revers2_txt", "D_Revers2 "+DoubleToStr(D_Revers2,4), FontSize, "Tahoma", LimeGreen);
}
else
{
ObjectMove("D_Revers2", 0,Time[1],D_Revers2);
ObjectMove("D_Revers2_txt", 0,Time[25],D_Revers2);
}
if (ObjectFind("D_Revers3") != 0)
{
ObjectCreate("D_Revers3",OBJ_HLINE,0,Time[25],D_Revers3,Time[1],D_Revers3);
ObjectCreate("D_Revers3_txt",OBJ_TEXT,0,Time[25],D_Revers3,Time[1],D_Revers3);
ObjectSet("D_Revers3",OBJPROP_COLOR,Yellow);
ObjectSet("D_Revers3",OBJPROP_WIDTH,1);
ObjectSet("D_Revers3",OBJPROP_STYLE,STYLE_DOT);
ObjectSetText("D_Revers3_txt", "D_Revers3 "+DoubleToStr(D_Revers3,4), FontSize, "Tahoma", Yellow);
}
else
{
ObjectMove("D_Revers3", 0,Time[1],D_Revers3);
ObjectMove("D_Revers3_txt", 0,Time[25],D_Revers3);
}
if (ObjectFind("Target1") != 0)
{
ObjectCreate("Target1",OBJ_HLINE,0,Time[25],Target1,Time[1],Target1);
ObjectCreate("Target1_txt",OBJ_TEXT,0,Time[10],Target1,Time[1],Target1);
ObjectSet("Target1",OBJPROP_COLOR,Goldenrod);
ObjectSet("Target1",OBJPROP_WIDTH,2);
ObjectSet("Target1",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText("Target1_txt", "Target1 "+DoubleToStr(Target1,4), FontSize, "Tahoma", Goldenrod);
}
else
{
ObjectMove("Target1", 0,Time[1],Target1);
ObjectMove("Target1_txt", 0,Time[10],Target1);
}
if (ObjectFind("Target2") != 0)
{
ObjectCreate("Target2",OBJ_HLINE,0,Time[25],Target2,Time[1],Target2);
ObjectCreate("Target2_txt",OBJ_TEXT,0,Time[10],Target2,Time[1],Target2);
ObjectSet("Target2",OBJPROP_COLOR,Goldenrod);
ObjectSet("Target2",OBJPROP_WIDTH,2);
ObjectSet("DTarget2",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText("Target2_txt", "Target2 "+DoubleToStr(Target2,4), FontSize, "Tahoma", Goldenrod);
}
else
{
ObjectMove("Target2", 0,Time[1],Target2);
ObjectMove("Target2_txt", 0,Time[10],Target2);
}
if (ObjectFind("Target3") != 0)
{
ObjectCreate("Target3",OBJ_HLINE,0,Time[25],Target3,Time[1],Target3);
ObjectCreate("Target3_txt",OBJ_TEXT,0,Time[10],Target3,Time[1],Target3);
ObjectSet("Target3",OBJPROP_COLOR,Goldenrod);
ObjectSet("Target3",OBJPROP_WIDTH,2);
ObjectSet("Target3",OBJPROP_STYLE,STYLE_SOLID);
ObjectSetText("Target3_txt", "Target3 "+DoubleToStr(Target3,4), FontSize, "Tahoma", Goldenrod);
}
else
{
ObjectMove("Target3", 0,Time[1],Target3);
ObjectMove("Target3_txt", 0,Time[10],Target3);
}
Comment("Dot B retrace of X-A: ",(PointB-PointA)/(PointX-PointA),"\n",
"Dot C retrace of X-A: ",(PointC-PointA)/(PointX-PointA),"\n",
"Dot C retrace of A-B: ",(PointB-PointC)/(PointB-PointA));
}
return(0);
}
//+------------------------------------------------------------------+
Comments