ZigAndZag(1)
Download scriptThis script is designed as a technical analysis tool for MetaTrader 4, specifically engineered to identify market trends and generate precise trading signals by analyzing price fluctuations. It functions by categorizing market movements into different "scales" of volatility to distinguish between minor noise and significant trend shifts.
Core Logic Overview
The tool operates using a multi-layered approach, processing historical data through three distinct phases to filter out market "noise" and identify actionable points of entry.
1. Data Filtering and Point Identification
The logic begins by scanning the price history to identify key structural points. It looks for specific highs and lows over two different time horizons:
- The "Slalom" (Short-term): This identifies smaller, more frequent fluctuations in price. The script tracks these to see how the market "wiggles" on a micro-level.
- The "KeelOver" (Long-term): This identifies much larger, broader structural shifts in price. It acts as the backbone of the analysis, helping to define the primary direction of the market.
The script includes a "Backstep" mechanism which ensures that if multiple high or low points occur too close together, only the most significant one is kept, preventing the chart from becoming cluttered with redundant information.
2. Trend and Structure Construction
Once the highs and lows are identified, the script performs a secondary refinement:
- Trend Identification: It determines whether the overall market is moving upward or downward based on the "KeelOver" points.
- Linear Trend Stretching: It creates a continuous "thread" or path of these structural points. This allows the tool to visualize a smooth, long-term trend line that connects significant turning points while ignoring minor price spikes.
3. Signal Generation (The "Scalpel")
The final phase is where the script produces actual trading signals (displayed as arrows on the chart). It uses the interaction between the short-term "Slalom" points and the long-term "Trend" to make decisions:
- In an Uptrend: The tool looks for specific "Slalom" behaviors. If the price reaches a significant level relative to the previous point, it may trigger a Buy Signal. It also monitors for potential reversals to set "Limit Orders."
- In a Downtrend: Conversely, it looks for specific downward movements to trigger Sell Signals.
- Logic Safeguards: The script includes logic to "cancel" or "cleanse" signals. If the price moves back and fails to meet the required criteria (the "LimitPoints"), the signal is removed. This ensures that only high-probability setups remain visible on the chart.
Summary of Visual Output
Users will see a combination of trend lines and specific markers:
- Trend Paths: A visual representation of the primary market flow.
- Buy Arrows: Specific entry points for long positions when the short-term movement aligns with the long-term trend.
- Sell Arrows: Specific entry points for short positions when the short-term movement aligns with the long-term trend.
- Limit Orders: Markers indicating potential price zones where a trade might become viable if the market reaches those levels.
//+------------------------------------------------------------------+
//| ZigAndZagScalpel.mq4 |
//| Bookkeeper, 2006, yuzefovich@gmail.com |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 7 // Èëè 8 - äëÿ testBuffer
#property indicator_color1 Aqua
#property indicator_color2 Black
#property indicator_color3 Black
#property indicator_color4 Black
#property indicator_color5 Yellow
#property indicator_color6 MediumSpringGreen
#property indicator_color7 OrangeRed
//#property indicator_color8 Yellow // Äëÿ ïîäáîðà ÷åãî-íèáóäü
extern int KeelOver=55; // Äëÿ M15
extern int Slalom=17; // Äëÿ M15
double KeelOverZigAndZagSECTION[];
double KeelOverZagBuffer[];
double SlalomZigBuffer[];
double SlalomZagBuffer[];
double LimitOrdersBuffer[];
double BuyOrdersBuffer[];
double SellOrdersBuffer[];
//double testBuffer[];
//+------------------------------------------------------------------+
int shift,back,CountBar,Backstep=3;
int LastSlalomZagPos,LastSlalomZigPos,LastKeelOverZagPos,LastKeelOverZigPos;
double Something,LimitPoints,Navel;
double CurKeelOverZig,CurKeelOverZag,CurSlalomZig,CurSlalomZag;
double LastSlalomZag,LastSlalomZig,LastKeelOverZag,LastKeelOverZig;
bool TrendUp,SetBuyOrder,SetLimitOrder,SetSellOrder,Second=false;
string LastZigOrZag="None";
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int init()
{
SetIndexBuffer(0,KeelOverZigAndZagSECTION);
SetIndexStyle(0,DRAW_SECTION,STYLE_DOT);//DRAW_SECTION èëè DRAW_NONE
SetIndexEmptyValue(0,0.0);
SetIndexBuffer(1,KeelOverZagBuffer);
SetIndexStyle(1,DRAW_NONE);
SetIndexEmptyValue(1,0.0);
SetIndexBuffer(2,SlalomZigBuffer);
SetIndexStyle(2,DRAW_NONE);
SetIndexEmptyValue(2,0.0);
SetIndexBuffer(3,SlalomZagBuffer);
SetIndexStyle(3,DRAW_NONE);
SetIndexEmptyValue(3,0.0);
SetIndexBuffer(4,LimitOrdersBuffer);
SetIndexStyle(4,DRAW_ARROW);
SetIndexArrow(4,108);
SetIndexEmptyValue(4,0.0);
SetIndexBuffer(5,BuyOrdersBuffer);
SetIndexStyle(5,DRAW_ARROW);
SetIndexArrow(5,233);
SetIndexEmptyValue(5,0.0);
SetIndexBuffer(6,SellOrdersBuffer);
SetIndexStyle(6,DRAW_ARROW);
SetIndexArrow(6,234);
SetIndexEmptyValue(6,0.0);
// SetIndexStyle(7,DRAW_SECTION);
// SetIndexBuffer(7,testBuffer);
// SetIndexEmptyValue(7,0.0);
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int start()
{
CountBar=Bars-KeelOver;
LimitPoints=Ask-Bid;
if(CountBar<=3*KeelOver) return(-1); // Ìàëîâàòî áóäåò
if(KeelOver<=2*Slalom) return(-1); // Òùàòåëüíåå íàäî
// Çà÷èñòêà íåïðàâèëüíîé èñòîðèè
for(shift=Bars-1; shift>Bars-KeelOver; shift--)
{
SlalomZagBuffer[shift]=0.0;
SlalomZigBuffer[shift]=0.0;
KeelOverZagBuffer[shift]=0.0;
KeelOverZigAndZagSECTION[shift]=0.0;
LimitOrdersBuffer[shift]=0.0;
BuyOrdersBuffer[shift]=0.0;
SellOrdersBuffer[shift]=0.0;
// testBuffer[shift]=0.0;
}
//+---Ïåðâûé ïîõîä ïî èñòîðèè----------------------------------------+
The_First_Crusade();
//+---Âòîðîé ïðîõîä ïî èñòîðè÷åñêèì ìåñòàì---------------------------+
//+---ñ öåëüþ ïîä÷èñòêè íåâåðíî ïîíÿòûõ ñîáûòèé----------------------+
LastSlalomZag=-1; LastSlalomZagPos=-1;
LastSlalomZig=-1; LastSlalomZigPos=-1;
LastKeelOverZag=-1; LastKeelOverZagPos=-1;
LastKeelOverZig=-1; LastKeelOverZigPos=-1;
The_Second_Crusade();
//+---Òðåòèé èñòîðè÷åñêèé ýêñêóðñ - ïîñòðîåíèå "òðåíäà"--------------+
//+---è ðàññòàíîâêà "òîðãîâûõ ñèãíàëîâ"------------------------------+
LastSlalomZag=-1; LastSlalomZagPos=-1;
LastSlalomZig=-1; LastSlalomZigPos=-1;
LastZigOrZag="None";
The_Third_Crusade();
//+---À ÷åãî ìû òåïåðü áóäåì èìåòü çäåñü è ñåé÷àñ?-------------------+
Shift_Zerro();
return(0);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void The_First_Crusade()
{
for(shift=CountBar; shift>0; shift--)
{
// Ïîèñê òî÷åê "âñòàë â ïîçó" - "óøåë ñ ðûíêà"
CurSlalomZig=Low[Lowest(NULL,0,MODE_LOW,Slalom,shift)];
CurSlalomZag=High[Highest(NULL,0,MODE_HIGH,Slalom,shift)];
// Ïðîâåðÿåì shift íà íàëè÷èå î÷åðåäíîãî ÑëàëîìÇèãà äëÿ âõîäà
// â ïîêóïêó èëè äëÿ âûõîäà èç ïðîäàæè
if(CurSlalomZig==LastSlalomZig) CurSlalomZig=0.0;
else
{
LastSlalomZig=CurSlalomZig;
if((Low[shift]-CurSlalomZig)>LimitPoints) CurSlalomZig=0.0;
else
{
// Íà èíòåðâàëå Backstep ìîæåò áûòü òîëüêî îäèí Çèã,
// îñòàâëÿåì òîëüêî ïîñëåäíèé, áîëåå ðàííèå óáèðàåì
for(back=1; back<=Backstep; back++)
{
Something=SlalomZigBuffer[shift+back];
if((Something!=0)&&(Something>CurSlalomZig))
SlalomZigBuffer[shift+back]=0.0;
}
}
}
// Ïðîâåðÿåì shift íà íàëè÷èå î÷åðåäíîãî ÑëàëîìÇàãà äëÿ âõîäà âíèç
// èëè äëÿ âûõîäà èç ïîêóïêè
if(CurSlalomZag==LastSlalomZag) CurSlalomZag=0.0;
else
{
LastSlalomZag=CurSlalomZag;
if((CurSlalomZag-High[shift])>LimitPoints) CurSlalomZag=0.0;
else
{
// Íà èíòåðâàëå Backstep ìîæåò áûòü òîëüêî îäèí Çàã,
// îñòàâëÿåì òîëüêî ïîñëåäíèé, áîëåå ðàííèå óáèðàåì
for(back=1; back<=Backstep; back++)
{
Something=SlalomZagBuffer[shift+back];
if((Something!=0)&&(Something<CurSlalomZag))
SlalomZagBuffer[shift+back]=0.0;
}
}
}
// Âñå, ÷òî íàøëè íîâåíüêîãî è ïóñòûøêè - êëàäåì â áóôåðà ñëàëîìà
SlalomZigBuffer[shift]=CurSlalomZig;
SlalomZagBuffer[shift]=CurSlalomZag;
// Èùåì òî÷êè ðàçâîðîòà äëÿ ïîñòðîåíèÿ "ëèíåéíîãî òðåíäà", ïðè ýòîì
// â áóôåð ðàçâîðîòîâ ZigAndZag ïîêà ÷òî áóäåì êëàñòü òîëüêî ÎâåðêèëüÇèãè
CurKeelOverZig=Low[Lowest(NULL,0,MODE_LOW,KeelOver,shift)];
CurKeelOverZag=High[Highest(NULL,0,MODE_HIGH,KeelOver,shift)];
// Ïðîâåðÿåì shift íà íàëè÷èå î÷åðåäíîãî ÎâåðêèëüÇèãà
if(CurKeelOverZig==LastKeelOverZig) CurKeelOverZig=0.0;
else
{
LastKeelOverZig=CurKeelOverZig;
if((Low[shift]-CurKeelOverZig)>LimitPoints) CurKeelOverZig=0.0;
else
{
// Íà èíòåðâàëå Backstep ìîæåò áûòü òîëüêî îäèí Çèã,
// îñòàâëÿåì òîëüêî ïîñëåäíèé, áîëåå ðàííèå óáèðàåì
for(back=1; back<=Backstep; back++)
{
Something=KeelOverZigAndZagSECTION[shift+back];
if((Something!=0)&&(Something>CurKeelOverZig))
KeelOverZigAndZagSECTION[shift+back]=0.0;
}
}
}
// Ïðîâåðÿåì shift íà íàëè÷èå î÷åðåäíîãî ÎâåðêèëüÇàãà
if(CurKeelOverZag==LastKeelOverZag) CurKeelOverZag=0.0;
else
{
LastKeelOverZag=CurKeelOverZag;
if((CurKeelOverZag-High[shift])>LimitPoints) CurKeelOverZag=0.0;
else
{
// Íà èíòåðâàëå Backstep ìîæåò áûòü òîëüêî îäèí Çàã,
// áîëåå ðàííèå óáèðàåì
for(back=1; back<=Backstep; back++)
{
Something=KeelOverZagBuffer[shift+back];
if((Something!=0)&&(Something<CurKeelOverZag))
KeelOverZagBuffer[shift+back]=0.0;
}
}
}
// Âñå, ÷òî íàøëè èëè íå íàøëè - êëàäåì â áóôåðà ðàçâîðîòîâ
KeelOverZigAndZagSECTION[shift]=CurKeelOverZig;
KeelOverZagBuffer[shift]=CurKeelOverZag;
}
return;
}
//+------------------------------------------------------------------+
void The_Second_Crusade()
{
// Ïðîñòî ïîä÷èñòêà ëèøíåãî
for(shift=CountBar; shift>0; shift--)
{
CurSlalomZig=SlalomZigBuffer[shift];
CurSlalomZag=SlalomZagBuffer[shift];
if((CurSlalomZig==0)&&(CurSlalomZag==0)) continue;
if(CurSlalomZag!=0)
{
if(LastSlalomZag>0)
{
if(LastSlalomZag<CurSlalomZag) SlalomZagBuffer[LastSlalomZagPos]=0;
else SlalomZagBuffer[shift]=0;
}
if(LastSlalomZag<CurSlalomZag || LastSlalomZag<0)
{
LastSlalomZag=CurSlalomZag;
LastSlalomZagPos=shift;
}
LastSlalomZig=-1;
}
if(CurSlalomZig!=0)
{
if(LastSlalomZig>0)
{
if(LastSlalomZig>CurSlalomZig) SlalomZigBuffer[LastSlalomZigPos]=0;
else SlalomZigBuffer[shift]=0;
}
if((CurSlalomZig<LastSlalomZig)||(LastSlalomZig<0))
{
LastSlalomZig=CurSlalomZig;
LastSlalomZigPos=shift;
}
LastSlalomZag=-1;
}
CurKeelOverZig=KeelOverZigAndZagSECTION[shift];
CurKeelOverZag=KeelOverZagBuffer[shift];
if((CurKeelOverZig==0)&&(CurKeelOverZag==0)) continue;
if(CurKeelOverZag !=0)
{
if(LastKeelOverZag>0)
{
if(LastKeelOverZag<CurKeelOverZag)
KeelOverZagBuffer[LastKeelOverZagPos]=0;
else KeelOverZagBuffer[shift]=0.0;
}
if(LastKeelOverZag<CurKeelOverZag || LastKeelOverZag<0)
{
LastKeelOverZag=CurKeelOverZag;
LastKeelOverZagPos=shift;
}
LastKeelOverZig=-1;
}
if(CurKeelOverZig!=0)
{
if(LastKeelOverZig>0)
{
if(LastKeelOverZig>CurSlalomZig)
KeelOverZigAndZagSECTION[LastKeelOverZigPos]=0;
else KeelOverZigAndZagSECTION[shift]=0;
}
if((CurKeelOverZig<LastKeelOverZig)||(LastKeelOverZig<0))
{
LastKeelOverZig=CurKeelOverZig;
LastKeelOverZigPos=shift;
}
LastKeelOverZag=-1;
}
}
return;
}
//+------------------------------------------------------------------+
void The_Third_Crusade()
{
bool first=true;
for(shift=CountBar; shift>0; shift--)
{
// Íèçâåãàåì ïðåæíèõ ïðîðîêîâ
LimitOrdersBuffer[shift]=0.0;
BuyOrdersBuffer[shift]=0.0;
SellOrdersBuffer[shift]=0.0;
// Çàäàåì öåíòð ìèðîçäàíüÿ èíòåðâàëà shift (ïî ëþáîìó -
// ñïîñîá áîëüøîãî ïîëèòè÷åñêîãî âåñà íå èìååò)
Navel=(5*Close[shift]+2*Open[shift]+High[shift]+Low[shift])/9;
// Åñëè îâåðêèëü - ñìîòðèì,
// êóäà (ìîæåò áûòü) äàëüøå ñåéìîìåíòíî ïîéäåì: ââåðõ èëè âíèç
if(KeelOverZigAndZagSECTION[shift]!=0.0)
{
TrendUp=true;
first=false;
}
if(KeelOverZagBuffer[shift]!=0.0)
{
TrendUp=false;
first=false;
}
// Ñîáèðàåì â KeelOverZigAndZagSECTION è ÎâåðêèëüÇèãè, è ÎâåðêèëüÇàãè,
// è ïóñòûøêè - âñå â îäíó êó÷êó, òàêèì îáðàçîì ïîëó÷àåì äîëãîèãðàþùèé
// ZigAndZag, íàòÿãèâàÿ íèòü "òðåíäà" íà ïóïêè ðàçâîðîòíûõ ñâå÷åê
if(KeelOverZagBuffer[shift]!=0.0 || KeelOverZigAndZagSECTION[shift]!=0.0)
{
KeelOverZigAndZagSECTION[shift]=Navel;
}
else KeelOverZigAndZagSECTION[shift]=0.0;
// Ïðîâåðÿåì shift íà íàëè÷èå ÑëàëîìÇèãà èëè ÑëàëîìÇàãà
if(SlalomZigBuffer[shift]!=0.0)
{
LastZigOrZag="Zig";
LastSlalomZig=Navel;
SetBuyOrder=false;
SetLimitOrder=false;
SetSellOrder=false;
}
if(SlalomZagBuffer[shift]!=0.0)
{
LastZigOrZag="Zag";
LastSlalomZag=Navel;
SetBuyOrder=false;
SetLimitOrder=false;
SetSellOrder=false;
}
// è, åñëè íè ÑëàëîìÇèãà, íè ÑëàëîìÇàãà óæå íåò,
// à îâåðêèëü óæå áûë - ñìîòðèì, à ÷òî åñòü ïî âõîäó-âûõîäó
if(SlalomZigBuffer[shift]==0.0 &&
SlalomZagBuffer[shift]==0.0 &&
first==false) Slalom_With_A_Scalpel();
}
return;
}
//+------------------------------------------------------------------+
void Shift_Zerro()
{
shift=0;
Navel=(5*Close[0]+2*Open[0]+High[0]+Low[0])/9;
Slalom_With_A_Scalpel();
KeelOverZigAndZagSECTION[0]=Navel;
return;
}
//+------------------------------------------------------------------+
void Slalom_With_A_Scalpel()
{
// Ïðîâåðÿåì ñóùåñòâóþùèé ñèãíàë íà èìååò ïðàâî áûòü
// èëè íà åñëè íå ñòîèò, à õîòåëîñü áû:
// åñëè õîä ÷èñòî êîíêðåòíî ïî æèçíè - çàáèâàåì Ñòðåëêó íà äåíüãè,
// åñëè ïðîòèâ - ñòàâèì íà øóõåð Øàðèêà Äåëàé-Íîãè
if(LastZigOrZag=="Zig")
{
if(TrendUp==true)
{
if((Navel-LastSlalomZig)>=LimitPoints && SetBuyOrder==false)
{
SetBuyOrder=true;
BuyOrdersBuffer[shift]=Low[shift+1];
LastSlalomZigPos=shift;
}
if(Navel<=LastSlalomZig && SetBuyOrder==true)
{
SetBuyOrder=false;
BuyOrdersBuffer[LastSlalomZigPos]=0.0;
LastSlalomZigPos=-1;
}
}
if(TrendUp==false)
{
if(Navel>LastSlalomZig && SetLimitOrder==false)
{
SetLimitOrder=true;
LimitOrdersBuffer[shift]=Navel;
// LimitOrdersBuffer[shift]=Close[shift];
LastSlalomZigPos=shift;
}
if(Navel<=LastSlalomZig && SetLimitOrder==true)
{
SetLimitOrder=false;
LimitOrdersBuffer[LastSlalomZigPos]=0.0;
LastSlalomZigPos=-1;
}
}
}
if(LastZigOrZag=="Zag")
{
if(TrendUp==false)
{
if((LastSlalomZag-Navel)>=LimitPoints && SetSellOrder==false)
{
SetSellOrder=true;
SellOrdersBuffer[shift]=High[shift+1];
LastSlalomZagPos=shift;
}
if(Navel>=LastSlalomZag && SetSellOrder==true)
{
SetSellOrder=false;
SellOrdersBuffer[LastSlalomZagPos]=0.0;
LastSlalomZagPos=-1;
}
}
if(TrendUp==true)
{
if(LastSlalomZag>Navel && SetLimitOrder==false)
{
SetLimitOrder=true;
LimitOrdersBuffer[shift]=Navel;
// LimitOrdersBuffer[shift]=Close[shift];
LastSlalomZagPos=shift;
}
if(Navel>=LastSlalomZag && SetLimitOrder==true)
{
SetLimitOrder=false;
LimitOrdersBuffer[LastSlalomZagPos]=0.0;
LastSlalomZagPos=-1;
}
}
}
return;
}
//+--Ñîáñòâåííî, ÿ âñå ñêàçàë. Çàáàâíî, åñëè âñå ýòî ðàáîòàòü áóäåò--+
//+------------------------------------------------------------------+
Comments