3 Level ZZ Semafor

Hi,
I tried on my own but I couldn't figure it out so I need someone who knows how and is willing to do it to help me. I found this indicator an meta trader and I tried it and it is really good.
Here is the explanation how to trade it https://www.youtube.com/watch?v=rnYLiQiorOQ&t=15s.
Thanks for your help.
here is the MT4 code

//+------------------------------------------------------------------+
//| 3_Level_ZZ_Semafor.mq4 |
//+------------------------------------------------------------------+
#property copyright "asystem2000"
#property link "asystem2000@yandex.ru"

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Chocolate
#property indicator_color2 Chocolate
#property indicator_color3 MediumVioletRed
#property indicator_color4 MediumVioletRed
#property indicator_color5 Yellow
#property indicator_color6 Yellow

//---- input parameters
extern int delta = 0;
extern double Period1=5;
extern double Period2=13;
extern double Period3=34;
extern string Dev_Step_1="1,3";
extern string Dev_Step_2="8,5";
extern string Dev_Step_3="13,8";
extern int Symbol_1_Kod=140;
extern int Symbol_2_Kod=141;
extern int Symbol_3_Kod=142;

//---- buffers
double FP_BuferUp[];
double FP_BuferDn[];
double NP_BuferUp[];
double NP_BuferDn[];
double HP_BuferUp[];
double HP_BuferDn[];

int F_Period;
int N_Period;
int H_Period;
int Dev1;
int Stp1;
int Dev2;
int Stp2;
int Dev3;
int Stp3;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
// --------- Êîððåêòèðóåì ïåðèîäû äëÿ ïîñòðîåíèÿ ÇèãÇàãîâ
if (Period1>0) F_Period=MathCeil(Period1Period()); else F_Period=0;
if (Period2>0) N_Period=MathCeil(Period2
Period()); else N_Period=0;
if (Period3>0) H_Period=MathCeil(Period3*Period()); else H_Period=0;

//---- Îáðàáàòûâàåì 1 áóôåð
if (Period1>0)
{
SetIndexStyle(0,DRAW_ARROW,0,1);
SetIndexArrow(0,Symbol_1_Kod);
SetIndexBuffer(0,FP_BuferUp);
SetIndexEmptyValue(0,0.0);

SetIndexStyle(1,DRAW_ARROW,0,1);
SetIndexArrow(1,Symbol_1_Kod);
SetIndexBuffer(1,FP_BuferDn);
SetIndexEmptyValue(1,0.0);
}

//---- Îáðàáàòûâàåì 2 áóôåð
if (Period2>0)
{
SetIndexStyle(2,DRAW_ARROW,0,1);
SetIndexArrow(2,Symbol_2_Kod);
SetIndexBuffer(2,NP_BuferUp);
SetIndexEmptyValue(2,0.0);

SetIndexStyle(3,DRAW_ARROW,0,1);
SetIndexArrow(3,Symbol_2_Kod);
SetIndexBuffer(3,NP_BuferDn);
SetIndexEmptyValue(3,0.0);
}
//---- Îáðàáàòûâàåì 3 áóôåð
if (Period3>0)
{
SetIndexStyle(4,DRAW_ARROW,0,2);
SetIndexArrow(4,Symbol_3_Kod);
SetIndexBuffer(4,HP_BuferUp);
SetIndexEmptyValue(4,0.0);

SetIndexStyle(5,DRAW_ARROW,0,2);
SetIndexArrow(5,Symbol_3_Kod);
SetIndexBuffer(5,HP_BuferDn);
SetIndexEmptyValue(5,0.0);
}
// Îáðàáàòûâàåì çíà÷åíèÿ äåâèàöèé è øàãîâ
int CDev=0;
int CSt=0;
int Mass[];
int C=0;
if (IntFromStr(Dev_Step_1,C, Mass)==1)
{
Stp1=Mass[1];
Dev1=Mass[0];
}

if (IntFromStr(Dev_Step_2,C, Mass)==1)
{
Stp2=Mass[1];
Dev2=Mass[0];
}

if (IntFromStr(Dev_Step_3,C, Mass)==1)
{
Stp3=Mass[1];
Dev3=Mass[0];
}
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----

//----
return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
if (Period1>0) CountZZ(FP_BuferUp,FP_BuferDn,Period1,Dev1,Stp1);
if (Period2>0) CountZZ(NP_BuferUp,NP_BuferDn,Period2,Dev2,Stp2);
if (Period3>0) CountZZ(HP_BuferUp,HP_BuferDn,Period3,Dev3,Stp3);
return(0);
}
//+------------------------------------------------------------------+
// äîïîëíèòåëüíûå ôóíêöèè
//int Take

//+------------------------------------------------------------------+
//| Ôóíêö ôîðìèðîâàíèÿ ÇèãÇàãà |
//+------------------------------------------------------------------+
int CountZZ( double& ExtMapBuffer[], double& ExtMapBuffer2[], int ExtDepth, int ExtDeviation, int ExtBackstep )
{
int shift, back,lasthighpos,lastlowpos;
double val,res;
double curlow,curhigh,lasthigh,lastlow;

for(shift=Bars-ExtDepth; shift>=0; shift--)
{
val=Low[Lowest(NULL,0,MODE_LOW,ExtDepth,shift)];
if(val==lastlow) val=0.0;
else
{
lastlow=val;
if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
else
{
for(back=1; back<=ExtBackstep; back++)
{
res=ExtMapBuffer[shift+back];
if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0;
}
}
}

      ExtMapBuffer[shift]=val-(delta*Point);
  //--- high
  val=High[Highest(NULL,0,MODE_HIGH,ExtDepth,shift)];
  if(val==lasthigh) val=0.0;
  else 
    {
     lasthigh=val;
     if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
     else
       {
        for(back=1; back<=ExtBackstep; back++)
          {
           res=ExtMapBuffer2[shift+back];
           if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0; 
          } 
       }
    }
  ExtMapBuffer2[shift]=val+(delta*Point);
 }

// final cutting
lasthigh=-1; lasthighpos=-1;
lastlow=-1; lastlowpos=-1;

for(shift=Bars-ExtDepth; shift>=0; shift--)
{
curlow=ExtMapBuffer[shift];
curhigh=ExtMapBuffer2[shift];
if((curlow==0)&&(curhigh==0)) continue;
//---
if(curhigh!=0)
{
if(lasthigh>0)
{
if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
else ExtMapBuffer2[shift]=0;
}
//---
if(lasthigh<curhigh || lasthigh<0)
{
lasthigh=curhigh;
lasthighpos=shift;
}
lastlow=-1;
}
//----
if(curlow!=0)
{
if(lastlow>0)
{
if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
else ExtMapBuffer[shift]=0;
}
//---
if((curlow<lastlow)||(lastlow<0))
{
lastlow=curlow;
lastlowpos=shift;
}
lasthigh=-1;
}
}

for(shift=Bars-1; shift>=0; shift--)
{
if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
else
{
res=ExtMapBuffer2[shift];
if(res!=0.0) ExtMapBuffer2[shift]=res;
}
}
}

int Str2Massive(string VStr, int& M_Count, int& VMass[])
{
int val=StrToInteger( VStr);
if (val>0)
{
M_Count++;
int mc=ArrayResize(VMass,M_Count);
if (mc==0)return(-1);
VMass[M_Count-1]=val;
return(1);
}
else return(0);
}

int IntFromStr(string ValStr,int& M_Count, int& VMass[])
{

if (StringLen(ValStr)==0) return(-1);
string SS=ValStr;
int NP=0; 
string CS;
M_Count=0;
ArrayResize(VMass,M_Count);
while (StringLen(SS)>0)
  {
        NP=StringFind(SS,",");
        if (NP>0)
           {
             CS=StringSubstr(SS,0,NP);
             SS=StringSubstr(SS,NP+1,StringLen(SS));  
           }
           else
           {
             if (StringLen(SS)>0)
                {
                  CS=SS;
                  SS="";
                }
           }
        if (Str2Massive(CS,M_Count,VMass)==0) 
           {
             return(-2);
           }
  }
return(1);    

}

It looks like I figured it out.
It is very slow and needs some more work to make it look good.
Enjoy!

_SECTION_BEGIN("3 level ZZ Semafor");
//+------------------------------------------------------------------+ 
//|                                        3_Level_ZZ_Semafor.mq4    | 
//+------------------------------------------------------------------+ 
//#property copyright "asystem2000" 
//#property link      "asystem2000@yandex.ru" 
ExtMapBuffer=0;
ExtMapBuffer2=0;
lastlow=-1;
lasthigh=-1;
Bars=BarCount-1;
point=param("Point",0.001,0.00001,100,0.00001);
delta  = param("Delta",10,1,100);
F_Period= param("Period 1", 5,1,100); 
N_Period= param("Period 2",13,1,100); 
H_Period= param("Period 3",34,1,100); 

Stp1=param("Stp1",1,1,100);
Dev1=param("Dev1",3,1,100);
Stp2=param("Stp2",8,1,100);
Dev2=param("Dev2",5,1,100);
Stp3=param("Stp3",13,1,100);
Dev3=param("Dev3",8,1,100);

mass=0;


FP_BuferUp=0;
 FP_BuferDn=0; 
 NP_BuferUp=0;
 NP_BuferDn=0; 
 HP_BuferUp=0;
 HP_BuferDn=0; 

CDev=0;
CSt=0;
Cnm=0;  


procedure Countzz(ExtMapBuffer, ExtMapBuffer2, ExtDepth, ExtDeviation, ExtBackstep)
{
val=llv(l,extdepth);
lastlow=-1;
lasthigh=-1;
for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      val=llv(l[shift],extdepth);
      if(val[shift]==lastlow[shift]) val=0.0;
      else 
        { 
         lastlow[shift]=val[shift]; 
         if((L[shift]-val[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtMapBuffer[shift+back];
               if((res!=0)&&(res>val[shift])) ExtMapBuffer[shift+back]=0.0; 
              }
           }
        } 
        
          ExtMapBuffer[shift]=val[shift]-(delta*Point);
          
      //--- high
      val=hhv(High[shift],ExtDepth);
      if(val[shift]==lasthigh[shift]) val=0.0;
      else 
        {
         lasthigh[shift]=val[shift];
         if((val[shift]-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtMapBuffer2[shift+back];
               if((res!=0)&&(res<val[shift])) ExtMapBuffer2[shift+back]=0.0; 
              } 
           }
        }
      ExtMapBuffer2[shift]=val[shift]+(delta*Point);

     }
          
   // final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtMapBuffer[shift];
      curhigh=ExtMapBuffer2[shift];

      if((curlow==0)&&(curhigh==0)) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtMapBuffer2[lasthighpos]=0;
            else ExtMapBuffer2[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtMapBuffer[lastlowpos]=0;
            else ExtMapBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
  
   for(shift=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         res=ExtMapBuffer2[shift];
         if(res!=0.0) ExtMapBuffer2[shift]=res;
        }
     }
     colr=IIf(ExtDeviation==3,colorgreen,IIf(ExtDeviation==5,colorblue,coloryellow));
     PlotShapes(IIf(ExtMapBuffer2>1,IIf(ExtDeviation==3,shapeDigit1,IIf(ExtDeviation==5,shapeDigit2,shapeDigit3)),shapeNone),colr,0,H,10+2*ExtDeviation);
     PlotShapes(IIf(ExtMapBuffer>1,IIf(ExtDeviation==3,shapeDigit1,IIf(ExtDeviation==5,shapeDigit2,shapeDigit3)),shapeNone),colr,0,L,-10-2*ExtDeviation);
     //Plot(IIf(ExtMapBuffer>10,ExtMapBuffer,-1E10),"extmapbuffer",ExtDeviation+1,1);
 }  

  

//int start() 


CountZZ(FP_BuferUp,FP_BuferDn,F_Period,Dev1,Stp1);

//FP_BuferUp=ExtMapBuffer;
//FP_BuferDn=ExtMapBuffer2;
//Plot(FP_BuferUp,"1st2",4,1);
//Plot(FP_BuferDn,"1st1",3,1);
//Plot(Lastlow,"1stL",3,1);
//Plot(Lasthigh,"1stH",4,1);
CountZZ(NP_BuferUp,NP_BuferDn,n_Period,Dev2,Stp2);
//NP_BuferUp=ExtMapBuffer;
//NP_BuferDn=ExtMapBuffer2;
//Plot(NP_BuferUp,"2st2",5,1);
//Plot(NP_BuferDn,"2st1",6,1);
//Plot(Lastlow*2,"2ndL",5,1);
//Plot(Lasthigh*2,"2ndH",6,1);
CountZZ(HP_BuferUp,HP_BuferDn,h_Period,Dev3,Stp3);
//HP_BuferUp=ExtMapBuffer;
//HP_BuferDn=ExtMapBuffer2;
//Plot(HP_BuferUp,"3st2",7,1);
//Plot(HP_BuferDn,"3st1",8,1);

//Plot(Lastlow*3,"3rdL",7,1);
//Plot(Lasthigh*3,"3rdH",8,1);
_SECTION_END();

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();
1 Like