ZigAndZag_005
Download scriptThis script is designed to identify market structure and provide specific trading signals by analyzing price movements through three distinct layers of logic. It combines traditional trend-following principles with a "scalpel-like" approach to filtering out market noise.
Core Logic Overview
The script operates by processing historical data in three successive stages (referred to in the code as "Crusades") to determine the current market environment and pinpoint high-probability entry points.
1. Structural Foundation (The First Layer)
The script first scans historical price data to identify significant peaks and valleys. It uses two different settings to do this:
- Slalom Points: These are smaller, more frequent price fluctuations used to capture immediate movements.
- KeelOver Points: These are larger, broader structural points used to define the primary trend of the market.
During this stage, the script ensures that only the most relevant peaks or valleys are kept, removing any redundant data points that occur too close together (based on a "Backstep" parameter).
2. Trend Filtering and Refinement (The Second Layer)
Once the initial points are identified, the script performs a secondary cleanup. It validates these points against one another to ensure they form a logical sequence. This prevents "false positives"—where a small price flicker might be mistaken for a major trend change. It essentially creates a smooth, filtered path of historical highs and lows.
3. Trend Synthesis and Signal Generation (The Third Layer)
In the final stage, the script merges the broad "KeelOver" structural data with the "Slalom" movements to create a comprehensive trend line. It then calculates a custom price point (an average of recent prices) to determine the current "navel" or center of gravity for the market.
The trading signals are generated based on the relationship between the current trend and the "Slalom" points:
- Trend Identification: If the primary structure is moving upward, the script identifies a bullish environment. If it is moving downward, it identifies a bearish environment.
- Buy/Sell Signals (Active): In a strong trend, the script looks for specific momentum breaks. For example, in an uptrend, if price pushes significantly beyond a previous Slalom point, it may trigger a Buy signal.
- Limit Orders (Counter-Trend/Pullback): If the market is moving against the current trend (or experiencing a pullback), the logic identifies specific "Navel" prices where a Limit Order might be placed, essentially preparing for a reversal or a continuation from a specific price level.
Visual Output
The script communicates these findings on the chart using various markers:
- Trend Lines: Dotted sections representing the primary structural path.
- Arrows: Specific visual markers indicating Buy positions, Sell positions, or potential Limit Order areas.
//+------------------------------------------------------------------+
//| 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 Lime
#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