//+------------------------------------------------------------------+
//|MTF NonLagMAv7.1_4TF_Bar  based on    MTF_MegaTrend_Bar_4TFNextM5 | 
//|                 from STEINITZ lee_yan_cn mod N4TF HAS Bar.mq4    |
//|                  Modified by Matsu, from #MTF Supertrend Bar.mq4 |
//| Forex-TSD.com                        Copyright ?2006, Eli hayun |
//|                                          http://www.elihayun.com |
//+------------------------------------------------------------------+
#property copyright "Copyright ?2006, Eli hayun"
#property link      "http://www.elihayun.com"

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 3
#property indicator_buffers 8
#property indicator_color1 LimeGreen
#property indicator_color2 Red
#property indicator_color3 LimeGreen
#property indicator_color4 Red
#property indicator_color5 LimeGreen
#property indicator_color6 Red
#property indicator_color7 LimeGreen
#property indicator_color8 Red

#define SIGNAL_BAR 1

//---- parameters
extern int		Length = 21;
//extern int method  = 3;
extern int		Price = 0;
//extern int MaMetod2  = 3;
//extern int MaPeriod2 = 2;
extern int     ColorBarBack   = 1;  //Bar back for color mode
extern int		BarWidth = 0;
extern color	BarColorUp = LimeGreen;
extern color	BarColorDown = Red;
extern color	TextColor = White;
extern bool		MTF_Hi_to_Lo = true;
extern bool		ShowArrows = true;
extern color	UpArrowColor = LimeGreen;
extern color	DownArrowColor = Red;
extern string	Note1 = "Use 2, 3 or 4 dots for arrows";
extern int		DotsforArrow = 3;
extern bool		AlertOnBarClose = true;
extern bool		SendAlert = true;
extern bool		SendEmail = false;
string			AlertMessageUp = "NLMA-MTF-4  Buy";
string			AlertMessageDn = "NLMA-MTF-4  Sell";



//---- buffers
double buf1_up[];
double buf1_dn[];
double buf2_up[];
double buf2_dn[];
double buf3_up[];
double buf3_dn[];
double buf4_up[];
double buf4_dn[];

string shortname = "";
int ArrSize = 112;//159;
int ArrowGap,t0,Signal;
int UniqueNum = 2283;
bool AlertDone = false;
int Period_1, Period_2, Period_3, Period_4;
string PerName_1, PerName_2, PerName_3, PerName_4;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
  
  
   SetIndexStyle(0,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(0,ArrSize);
   SetIndexBuffer(0,buf1_up);
   SetIndexEmptyValue(0,0.0);
   SetIndexLabel(0,"0_up");
   
   SetIndexStyle(1,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(1,ArrSize);
   SetIndexBuffer(1,buf1_dn);
   SetIndexEmptyValue(1,0.0);
   SetIndexLabel(1,"1_dn");
   
   SetIndexStyle(2,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(2,ArrSize);
   SetIndexBuffer(2,buf2_up);
   SetIndexEmptyValue(2,0.0);
   SetIndexLabel(2,"2_up");
   
   SetIndexStyle(3,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(3,ArrSize);
   SetIndexBuffer(3,buf2_dn);
   SetIndexEmptyValue(3,0.0);
   SetIndexLabel(3,"3_dn");
   
   SetIndexStyle(4,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(4,ArrSize);
   SetIndexBuffer(4,buf3_up);
   SetIndexEmptyValue(4,0.0);
   SetIndexLabel(4,"4_up");
   
   SetIndexStyle(5,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(5,ArrSize);
   SetIndexBuffer(5,buf3_dn);
   SetIndexEmptyValue(5,0.0);
   SetIndexLabel(5,"5_dn");
   
   SetIndexStyle(6,DRAW_ARROW,0,BarWidth,BarColorUp);
   SetIndexArrow(6,ArrSize);
   SetIndexBuffer(6,buf4_up);
   SetIndexEmptyValue(6,0.0);
   SetIndexLabel(6,"6_up");
   
   SetIndexStyle(7,DRAW_ARROW,0,BarWidth,BarColorDown);
   SetIndexArrow(7,ArrSize);
   SetIndexBuffer(7,buf4_dn);
   SetIndexEmptyValue(7,0.0);
   SetIndexLabel(7,"7_dn");
   /*
	SetIndexLabel(0,NULL);
	SetIndexLabel(1,NULL);
	SetIndexLabel(2,NULL);
	SetIndexLabel(3,NULL);
	SetIndexLabel(4,NULL);
	SetIndexLabel(5,NULL);
	SetIndexLabel(6,NULL);
	SetIndexLabel(7,NULL);
   */
	IndicatorDigits(0);
	
	getPeriod();
	
	PerName_1 = TimeFrameToString(Period_1);
	PerName_2 = TimeFrameToString(Period_2);
	PerName_3 = TimeFrameToString(Period_3);
	PerName_4 = TimeFrameToString(Period_4);
	
	shortname = "NLMA-MTF-4 ("+PerName_1+","+PerName_2+","+PerName_3+","+PerName_4+")";
	IndicatorShortName(shortname);
   
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
  	DeleteArrows();

   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+




int start()
{
   int counted_bars=IndicatorCounted();
   //---- check for possible errors
   if(counted_bars<0) return(-1);
   //---- the last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars+Period_4/Period();
   int i,tf;
   int Period_1_shift=0,Period_2_shift=0,Period_3_shift=0,Period_4_shift=0;
   double NonLagUpPeriod_1,NonLagDnPeriod_1,NonLagUpPeriod_2,NonLagDnPeriod_2,NonLagUpPeriod_3,NonLagDnPeriod_3,NonLagUpPeriod_4,NonLagDnPeriod_4;
   double Gap1,Gap2,Gap3,Gap4;
   
   
   if(MTF_Hi_to_Lo){Gap1 = 0.5; Gap2 = 1.0; Gap3 = 1.5; Gap4 = 2.0;}else{Gap1 = 2.0; Gap2 = 1.5; Gap3 = 1.0; Gap4 = 0.5;}
   //-------------------------------1----------------------------------------   
   double dif = Time[0] - Time[1];
   for ( i=ObjectsTotal()-1; i>-1; i--)
      {
         if (StringFind(ObjectName(i),"FF_"+UniqueNum+"_") >= 0)  ObjectDelete(ObjectName(i));
      }
      
   double shift = 0.10;
   for ( tf=1; tf<=4; tf++)
      {  
         string txt = "??";
         double gp;
         switch (tf)
         {
            case 1: txt = TimeFrameToString(Period_1);  gp = Gap1 + shift; break;
            case 2: txt = TimeFrameToString(Period_2);  gp = Gap2 + shift; break;
            case 3: txt = TimeFrameToString(Period_3);  gp = Gap3 + shift; break;
            case 4: txt = TimeFrameToString(Period_4);  gp = Gap4 + shift; break;
         }
         string name = "FF_"+UniqueNum+"_"+tf+"_"+txt;
         ObjectCreate(name, OBJ_TEXT, WindowFind(shortname), iTime(NULL,0,0)+dif*3, gp);
         ObjectSetText(name, txt,8,"Arial", TextColor);
      }
   
   
   
   //-------------------------------2----------------------------------------
   
	for(i=limit; i>=0; i--)
	{
		Period_1_shift = iBarShift(NULL,Period_1,Time[i]);
		Period_2_shift = iBarShift(NULL,Period_2,Time[i]);
		Period_3_shift = iBarShift(NULL,Period_3,Time[i]);
		Period_4_shift = iBarShift(NULL,Period_4,Time[i]);
		
		NonLagUpPeriod_1 = iCustom(NULL,Period_1,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,1,Period_1_shift) ;
		NonLagDnPeriod_1 = iCustom(NULL,Period_1,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,2,Period_1_shift) ;
		NonLagUpPeriod_2 = iCustom(NULL,Period_2,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,1,Period_2_shift) ;
		NonLagDnPeriod_2 = iCustom(NULL,Period_2,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,2,Period_2_shift) ;
		NonLagUpPeriod_3 = iCustom(NULL,Period_3,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,1,Period_3_shift) ;
		NonLagDnPeriod_3 = iCustom(NULL,Period_3,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,2,Period_3_shift) ;
		NonLagUpPeriod_4 = iCustom(NULL,Period_4,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,1,Period_4_shift) ;
		NonLagDnPeriod_4 = iCustom(NULL,Period_4,"NonLagMA_v7.1",Price,Length,0,0,1,ColorBarBack,2,Period_4_shift) ;
		
		if		( NonLagUpPeriod_1 != EMPTY_VALUE && NonLagDnPeriod_1 == EMPTY_VALUE)	{buf1_up[i] = Gap1; buf1_dn[i] = 0.0;}
		else if	( NonLagUpPeriod_1 == EMPTY_VALUE && NonLagDnPeriod_1 != EMPTY_VALUE)	{buf1_dn[i] = Gap1; buf1_up[i] = 0.0;}
		else if	( NonLagUpPeriod_1 != EMPTY_VALUE && NonLagDnPeriod_1 != EMPTY_VALUE)	{buf1_dn[i] = buf1_dn[i+1]; buf1_up[i] = buf1_up[i+1];}
		
		if		( NonLagUpPeriod_2 != EMPTY_VALUE && NonLagDnPeriod_2 == EMPTY_VALUE)	{buf2_up[i] = Gap2; buf2_dn[i] = 0.0;}
		else if	( NonLagUpPeriod_2 == EMPTY_VALUE && NonLagDnPeriod_2 != EMPTY_VALUE)	{buf2_dn[i] = Gap2; buf2_up[i] = 0.0;}
		else if	( NonLagUpPeriod_2 != EMPTY_VALUE && NonLagDnPeriod_2 != EMPTY_VALUE)	{buf2_dn[i] = buf2_dn[i+1]; buf2_up[i] = buf2_up[i+1];}
		
		if		( NonLagUpPeriod_3 != EMPTY_VALUE && NonLagDnPeriod_3 == EMPTY_VALUE)	{buf3_up[i] = Gap3; buf3_dn[i] = 0.0;}
		else if	( NonLagUpPeriod_3 == EMPTY_VALUE && NonLagDnPeriod_3 != EMPTY_VALUE)	{buf3_dn[i] = Gap3; buf3_up[i] = 0.0;}
		else if	( NonLagUpPeriod_3 != EMPTY_VALUE && NonLagDnPeriod_3 != EMPTY_VALUE)	{buf3_dn[i] = buf3_dn[i+1]; buf3_up[i] = buf3_up[i+1];}
		
		if		( NonLagUpPeriod_4 != EMPTY_VALUE && NonLagDnPeriod_4 == EMPTY_VALUE)	{buf4_up[i] = Gap4; buf4_dn[i] = 0.0;}
		else if	( NonLagUpPeriod_4 == EMPTY_VALUE && NonLagDnPeriod_4 != EMPTY_VALUE)	{buf4_dn[i] = Gap4; buf4_up[i] = 0.0;}
		else if	( NonLagUpPeriod_4 != EMPTY_VALUE && NonLagDnPeriod_4 != EMPTY_VALUE)	{buf4_dn[i] = buf4_dn[i+1]; buf4_up[i] = buf4_up[i+1];}
	}
	
	static int PrevSignal = 0, PrevTime = 0;
	if(SIGNAL_BAR > 0 && Time[0] <= PrevTime) return(0);
	PrevTime = Time[0];
	
	//DeleteArrows();
   
	if(ShowArrows)
	{
		if(DotsforArrow ==4)
		{
			for (i=limit; i>=0; i--)
			{
				if (AlertOnBarClose) t0 = i + 1;
				else t0 = i;
				
				if((buf1_dn[t0+1]==0.0 || buf2_dn[t0+1]==0.0 || buf3_dn[t0+1] ==0.0 || buf4_dn[t0+1]==0.0) && (buf1_dn[t0] !=0.0 && buf2_dn[t0] !=0.0 && buf3_dn[t0] !=0.0 && buf4_dn[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Down Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],High[t0]+ArrowGap*Point);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_ARROWCODE,234);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_COLOR,DownArrowColor);
					Signal=-1;
					DoAlerts(i,Signal);
				}
               
				else
				if ((buf1_up[t0+1]==0.0 || buf2_up[t0+1]==0.0 || buf3_up[t0+1] ==0.0 || buf4_up[t0+1]==0.0) && (buf1_up[t0] !=0.0 && buf2_up[t0] !=0.0 && buf3_up[t0] !=0.0 && buf4_up[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Up Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],Low[t0]-ArrowGap*Point);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_ARROWCODE,233);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_COLOR,UpArrowColor);
					Signal=1;
					DoAlerts(i,Signal);
				}
			}      
		}
		else if(DotsforArrow ==3)
		{
			for (i=limit; i>=0; i--)
			{
				if (AlertOnBarClose) t0 = i + 1;
				else t0 = i;
            
				if((buf1_dn[t0+1]==0.0 || buf2_dn[t0+1]==0.0 || buf3_dn[t0+1] ==0.0 ) && (buf1_dn[t0] !=0.0 && buf2_dn[t0] !=0.0 && buf3_dn[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Down Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],High[t0]+ArrowGap*2*Point);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_ARROWCODE,234);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_COLOR,DownArrowColor);
					Signal=-1;
					DoAlerts(i,Signal);
				}
               
				else
				if ((buf1_up[t0+1]==0.0 || buf2_up[t0+1]==0.0 || buf3_up[t0+1] ==0.0) && (buf1_up[t0] !=0.0 && buf2_up[t0] !=0.0 && buf3_up[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Up Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],Low[t0]-ArrowGap*Point);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_ARROWCODE,233);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_COLOR,UpArrowColor);
					Signal=1;
					DoAlerts(i,Signal);
				}
			}      
		}
      
		else if(DotsforArrow ==2)
		{
			for (i=limit; i>=0; i--)
			{
				if (AlertOnBarClose) t0 = i + 1;
                else t0 = i;
            
				if((buf1_dn[t0+1]==0.0 || buf2_dn[t0+1]==0.0) && (buf1_dn[t0] !=0.0 && buf2_dn[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Down Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],High[t0]+ArrowGap*2*Point);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_ARROWCODE,234);
					ObjectSet("Down Arrow"+Time[t0],OBJPROP_COLOR,DownArrowColor);
					Signal=-1;
					DoAlerts(i,Signal);
				}
               
				else
				if ((buf1_up[t0+1]==0.0 || buf2_up[t0+1]==0.0) && (buf1_up[t0] !=0.0 && buf2_up[t0] !=0.0))
				{
					ArrowGap = 0.5*MathCeil(iATR(NULL,0,14,i)/Point);
					ObjectCreate("Up Arrow"+Time[t0],OBJ_ARROW,0, Time[t0],Low[t0]-ArrowGap*Point);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_ARROWCODE,233);
					ObjectSet("Up Arrow"+Time[t0],OBJPROP_COLOR,UpArrowColor);
					Signal=1;
					DoAlerts(i,Signal);
				}
			}      
		}
	}

	return(0);
}


//+------------------------------------------------------------------+
void DoAlerts(int i, int signal)
{
	if (SendAlert && i == 0)
	{
		if (AlertDone == false)
		{
			if (signal > 0)
			{
				AlertDone = true;
				Alert(AlertMessageUp+" ",Symbol());
				PlaySound("Alert.wav");
				if (SendEmail)
				{SendMail(AlertMessageUp+" ",Symbol());}
			}
			else
			if (signal < 0)
			{
				AlertDone = true;
				Alert(AlertMessageDn+" ",Symbol());
				PlaySound("Alert.wav");
				if (SendEmail)
				{SendMail(AlertMessageDn+" ",Symbol());}
			}
			else
			{AlertDone = false;}
		}
	}
}


void DeleteArrows()
{
	for(int i = Bars; i>=0; i--)
	{
		ObjectDelete("Down Arrow"+ Time[i]);
		ObjectDelete("Up Arrow"+ Time[i]);
	}
}

//+------------------------------------------------------------------+
void getPeriod()
{
   switch(Period()) 
      {
         case 1: 
            Period_1=1;		Period_2=5;		Period_3=15;	Period_4=30;	break;
         case 5: 
            Period_1=5;		Period_2=15;	Period_3=30;	Period_4=60;	break;
         case 15: 
            Period_1=15;	Period_2=30;	Period_3=60;	Period_4=240;	break;
         case 30: 
            Period_1=30;	Period_2=60;	Period_3=240;	Period_4=1440;	break;
         case 60: 
            Period_1=60;	Period_2=240;	Period_3=1440;	Period_4=10080;	break;
         case 240: 
            Period_1=240;	Period_2=1440;	Period_3=10080;	Period_4=43200;	break;
         case 1440: 
            Period_1=1440;	Period_2=10080;	Period_3=43200;	Period_4=43200;	break;
         case 10080: 
            Period_1=10080;	Period_2=43200;	Period_3=43200;	Period_4=43200;	break;
         case 43200: 
            Period_1=43200;	Period_2=43200;	Period_3=43200;	Period_4=43200;	break;
      }
}

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="MN";
	}
	return(tfs);
}

