//+------------------------------------------------------------------+ 
//|   _TRO_COMPASS_ZZS                                               | 
//|                                                                  | 
//|   Copyright © 2008, Avery T. Horton, Jr. aka TheRumpledOne       |
//|                                                                  |
//|   PO BOX 43575, TUCSON, AZ 85733                                 |
//|                                                                  |
//|   GIFTS AND DONATIONS ACCEPTED                                   | 
//|                                                                  |
//|   therumpledone@gmail.com                                        |  
//+------------------------------------------------------------------+ 
//+------------------------------------------------------------------+
//|                                         3_Level_ZZ_Semafor.mq4   |
//|                                       "asystem2000@yandex.ru"    |
//+------------------------------------------------------------------+
#property  copyright "Copyright © 2008, Avery T. Horton, Jr. aka TRO" 
#property  link      "http://www.therumpledone.com/" 

//---- indicator settings 
#property indicator_separate_window
#property indicator_buffers 0
//#property indicator_minimum 0
//#property indicator_maximum 1



//---- indicator parameters  
 

//extern int win = 1;
extern int price.x.offset= 0 ;//250
extern int price.y.offset= -160 ;//-160

extern bool show.arrow = true ;
extern bool show.value = true ;
//extern int  myDecimals = 2 ;

extern string myFont       = "Arial Bold" ;
extern int    myFontSize   = 30 ;
extern int    myArrowSize  = 40 ;
extern int    myDigitSize  = 20 ;
extern int    xStart       = -600 ;
extern int    xOffSet      = 100 ;

//extern string Ind_Name_1 ="iMA";
extern color  myIndColor = DarkGray ;

extern double Period1=34; // 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;

/*

PARM6 FOR MA = 

PRICE_CLOSE	0	Close price.
PRICE_OPEN	1	Open price.
PRICE_HIGH	2	High price.
PRICE_LOW	3	Low price.
PRICE_MEDIAN	4	Median price, (high+low)/2.
PRICE_TYPICAL	5	Typical price, (high+low+close)/3.
PRICE_WEIGHTED	6	Weighted close price, (high+low+close+close)/4.


PARM3 FOR MA = 
MODE_SMA	0	Simple moving average,
MODE_EMA	1	Exponential moving average,
MODE_SMMA	2	Smoothed moving average,
MODE_LWMA	3	Linear weighted moving average.



extern double iParm3 = 5;
extern double iParm4 = 0;
extern double iParm5 = 1;  
extern double iParm6 = 0;
extern double iParm7 = 0;
extern double iParm8 = 0;
*/

extern color N_color  = Lime;
extern color NE_color = Lime;
extern color E_color  = Yellow;
extern color SE_color = Red;
extern color S_color  = Red;


//---- indicator buffers 



// int   Chart_Period    = PERIOD_H1;


//---- buffers






string Arrow12 = "ñ"; // 12 oclock
string Arrow2  = "ö";  // 2 oclock
string Arrow3  = "ð";  // 3 oclock
string Arrow5  = "ø";  // 5 oclock
string Arrow6  = "ò";  // 6 oclock


string tObjName01   ;
string tObjName02   ;
string tObjName03   ;
string tObjName04 , tObjName05, IndHead ;

double open    ;  
double close    ; 
double close1   ;  
double high    ;    
double high1    ;   
double low     ;    
double low1     ; 

double mid      ; 
double mid1    ; 


double pCount   ;

int   HighDir, LowDir, MidDir, Mid1Dir, CloseDir, ClOpDir ;
color HighColor, LowColor, MidColor, Mid1Color, CloseColor ;

string PriceDir   ;

string tPeriod   ; 

double cVal, pVal, hVal, lVal ;

int hShift, lShift ;

//+------------------------------------------------------------------+
int      totalLabels;
string   labelNames;
int      corner;
int      window; 
string   shortName ;
int      win ;
//+------------------------------------------------------------------+
//---- 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;

//+------------------------------------------------------------------+

string TimeFrameToString(int tf)
{
   string tfs;
   switch(tf) {
      case PERIOD_M1:  tfs="M1"  ; break;
      case PERIOD_M5:  tfs="M5"  ; break;
      case PERIOD_M15: tfs="M15" ; break;
      case PERIOD_M30: tfs="M30" ; break;
      case PERIOD_H1:  tfs="H1"  ; break;
      case PERIOD_H4:  tfs="H4"  ; break;
      case PERIOD_D1:  tfs="D1"  ; break;
      case PERIOD_W1:  tfs="W1"  ; break;
      case PERIOD_MN1: tfs="MN1";
   }
   return(tfs);
}

//+------------------------------------------------------------------+

color fColor( double i)
{
color rColor ;

    if ( i >= 0 ) rColor = N_color  ; else {  
                  rColor = S_color ; }  

return ( rColor );
}
//+------------------------------------------------------------------+

int fDirection( double xaEMA, double xaEMA1)
{
int rDir ;

if( xaEMA >= xaEMA1 ) {  rDir = 2;  }
else  { rDir = -2;  }   

return ( rDir );
}

 

//+------------------------------------------------------------------+


string fCompass( double i )
{
string rCompass ;

    if ( i == 2 ) rCompass = Arrow2  ; else {
    if ( i == 1 ) rCompass = Arrow2  ; else {
    if ( i == -1 ) rCompass = Arrow5  ; else {
    if ( i == -2 ) rCompass = Arrow5  ; else {      
    rCompass = Arrow3 ; } } } }
    
return ( rCompass );
}


//+------------------------------------------------------------------+

int init() 
  { 
   shortName  = MakeUniqueName("ZZS ","");
   labelNames = shortName;
   IndicatorShortName(shortName);
   totalLabels     = 0;
//----------------------     
  
   if (Period1>0) F_Period=MathCeil(Period1*Period()); 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; 
   
   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); 
  } 

int deinit() 
{ 
   while (totalLabels>0) { ObjectDelete(StringConcatenate(labelNames,totalLabels)); totalLabels--;}
  
DoDelObj( PERIOD_M1 ) ;
DoDelObj( PERIOD_M5 ) ;
DoDelObj( PERIOD_M15 ) ;  
DoDelObj( PERIOD_H1 ) ;
DoDelObj( PERIOD_H4 ) ;
DoDelObj( PERIOD_D1 ) ;
DoDelObj( PERIOD_W1 ) ;
DoDelObj( PERIOD_MN1 ) ;

   
}  

//+------------------------------------------------------------------+ 
//| Range                                                            | 
//+------------------------------------------------------------------+ 
int start() 
  { 

int xStart2 = xStart + xOffSet ;
int xStart3 = xStart + xOffSet*2 ;
int xStart4 = xStart + xOffSet*3 ;
int xStart5 = xStart + xOffSet*4 ;
int xStart6 = xStart + xOffSet*5 ;
int xStart7 = xStart + xOffSet*6 ;
int xStart8 = xStart + xOffSet*7 ;

win =    WindowFind(shortName);

bool sFirst = true ;

if ( sFirst ) {
sFirst = false ;
ObjectDelete(tObjName04);

ObjectsDeleteAll( win, 21);
ObjectsDeleteAll( win, 22);
ObjectsDeleteAll( win, 23);
}

IndHead =  "ZZS "  ;

DoHead(IndHead );

DoWork( PERIOD_M1 ) ;
DoShow( PERIOD_M1, xStart ) ;

DoWork( PERIOD_M5 ) ;
DoShow( PERIOD_M5, xStart2 ) ;

DoWork( PERIOD_M15 ) ;
DoShow( PERIOD_M15, xStart3 ) ;                      

DoWork( PERIOD_H1 ) ;
DoShow( PERIOD_H1, xStart4 ) ;

DoWork( PERIOD_H4 ) ;
DoShow( PERIOD_H4, xStart5 ) ;

DoWork( PERIOD_D1 ) ;
DoShow( PERIOD_D1, xStart6 ) ;

DoWork( PERIOD_W1 ) ;
DoShow( PERIOD_W1, xStart7 ) ;

DoWork( PERIOD_MN1 ) ;
DoShow( PERIOD_MN1, xStart8 ) ;

WindowRedraw();    
 


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

void DoWork( int myPeriod  )  
{

   if (Period1>0) CountZZ(FP_BuferUp,FP_BuferDn,Period1,Dev1,Stp1, myPeriod );
//   if (Period2>0) CountZZ(NP_BuferUp,NP_BuferDn,Period2,Dev2,Stp2, myPeriod );
//   if (Period3>0) CountZZ(HP_BuferUp,HP_BuferDn,Period3,Dev3,Stp3, myPeriod );        

/*                            
if( FP_BuferUp[0] > 0 ) cVal = FP_BuferUp[0] ;  
if( FP_BuferDn[0] > 0 ) cVal = FP_BuferDn[0] ;  
if( NP_BuferUp[0] > 0 ) cVal = NP_BuferUp[0] ;  
if( NP_BuferDn[0] > 0 ) cVal = NP_BuferDn[0] ;                             
if( HP_BuferUp[0] > 0 ) cVal = HP_BuferUp[0] ;  
if( HP_BuferDn[0] > 0 ) cVal = HP_BuferDn[0] ;                              
*/                       
      
if( hShift > lShift ) cVal = lVal; else cVal = hVal;
                                                                                                                      
pCount  = fDirection( hShift , lShift  ) ;

CloseColor = fColor( pCount ) ;

PriceDir = fCompass( pCount ) ;


}

//+------------------------------------------------------------------+ 
void DoDelObj( int lPeriod  )  
{

tObjName01 = labelNames +lPeriod +  "ZZS230" ;
tObjName02 = labelNames +lPeriod +  "ZZS231" ;
tObjName03 = labelNames +lPeriod +  "ZZS232" ;
//tObjName04 = labelNames +  "ZZS200" ;
tObjName05 = labelNames +lPeriod +  "ZZS235" ;

ObjectDelete(tObjName01);
ObjectDelete(tObjName02);
ObjectDelete(tObjName03);
ObjectDelete(tObjName04);
ObjectDelete(tObjName05);
}

//+------------------------------------------------------------------+ 
void DoShow( int lPeriod , int xInc)  
{

tObjName01 = labelNames +lPeriod +  "ZZS230" ;
tObjName02 = labelNames +lPeriod +  "ZZS231" ;
tObjName03 = labelNames +lPeriod +  "ZZS232" ;
tObjName05 = labelNames +lPeriod +  "ZZS235" ;


tPeriod  = TimeFrameToString( lPeriod ) ;

   ObjectCreate(tObjName01, OBJ_LABEL, win, 0, 0);//HiLow LABEL
   ObjectSetText(tObjName01, tPeriod, myFontSize, myFont, CloseColor );
   ObjectSet(tObjName01, OBJPROP_CORNER, 0);
   ObjectSet(tObjName01, OBJPROP_XDISTANCE,  xInc+980+price.x.offset); // 760
   ObjectSet(tObjName01, OBJPROP_YDISTANCE, 175+price.y.offset); // 160

int sInc = 0 ;

if(show.arrow){

sInc = 50 ;
   
   ObjectCreate(tObjName03, OBJ_LABEL, win, 0, 0);//HiLow LABEL
   ObjectSetText(tObjName03, PriceDir , myArrowSize , "Wingdings" , CloseColor );
   ObjectSet(tObjName03, OBJPROP_CORNER, 0);
   ObjectSet(tObjName03, OBJPROP_XDISTANCE, xInc+980+price.x.offset); // 765
   ObjectSet(tObjName03, OBJPROP_YDISTANCE, 210+price.y.offset); 
   
} //if(show.arrow)


if(show.value){
    
   ObjectCreate(tObjName05, OBJ_LABEL, win, 0, 0);//HiLow LABEL
   ObjectSetText(tObjName05, DoubleToStr(cVal,Digits) ,myDigitSize, myFont , CloseColor );
   ObjectSet(tObjName05, OBJPROP_CORNER, 0);
   ObjectSet(tObjName05, OBJPROP_XDISTANCE, xInc+980+price.x.offset); // 765
   ObjectSet(tObjName05, OBJPROP_YDISTANCE, sInc+210+price.y.offset); 
} //if(show.value)



}

//+------------------------------------------------------------------+ 

void DoHead( string dHead  )  
{

tObjName04 = labelNames +  "ZZS200" ;

   ObjectCreate(tObjName04, OBJ_LABEL, win, 0, 0);//HiLow LABEL
   ObjectSetText(tObjName04, dHead, myFontSize, myFont, myIndColor );
   ObjectSet(tObjName04, OBJPROP_CORNER, 0);
   ObjectSet(tObjName04, OBJPROP_XDISTANCE,  00+price.x.offset); // 760
   ObjectSet(tObjName04, OBJPROP_YDISTANCE, 210+price.y.offset); // 160
}

//+------------------------------------------------------------------+ 


// string next() { totalLabels++; return(totalLabels); }  

//+------------------------------------------------------------------+

 
string MakeUniqueName(string first, string rest)
{
   string result = first+(MathRand()%1001)+rest;

   while (WindowFind(result)> 0)
          result = first+(MathRand()%1001)+rest;
   return(result);
}


//+------------------------------------------------------------------+

int CountZZ( double& ExtMapBuffer[], double& ExtMapBuffer2[], int ExtDepth, int ExtDeviation, int ExtBackstep , int myPeriod )
  {
   int    shift, back,lasthighpos,lastlowpos;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      lShift = Lowest(NULL,myPeriod,MODE_LOW,ExtDepth,shift) ;
      val    = iLow(NULL,myPeriod,lShift) ;
//      val=Low[lShift];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         lVal = val;
//         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         if((iLow(NULL,myPeriod,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;
      //--- high
      hShift = Highest(NULL,myPeriod,MODE_HIGH,ExtDepth,shift) ;
      val    = iHigh(NULL,myPeriod,hShift) ;
//      val=High[hShift];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         hVal = val;
//         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         if((val- iHigh(NULL,myPeriod,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;
     }
   // 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);    
  }

//+------------------------------------------------------------------+