//+------------------------------------------------------------------+
//|                                                  MACD_1_line.mq4 |
//|                                      Copyright © 2010, DimDimych |
//|                                                     dm34@mail.ru |
//|                                && komposter komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "DimDimych"
#property link      "dm34@mail.ru"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 White
#property indicator_color2 Blue

extern int     FastEMA                    = 12;
extern int     SlowEMA                    = 26;
extern int     SignalSMA                  = 9;
extern bool    SoundAlerts                = true;
extern bool    DrawArrows                 = true;
extern int		Arrows_width			   	= 1;
extern bool		DrawTrendLine					= true;
extern int		TrendLine_width				= 2;
extern int		TrendLine_style				= STYLE_SOLID;
extern color	color_DN		            	= White;
extern color	color_UP		            	= Blue;
extern int		BarsCount						= 300;
extern int		MinBars							= 1;

double Buff_up[];
double Buff_dn[];
double Buff_temp[];
double Buff_temp_sig[];

string	short_name	= "";

int init() {

   IndicatorBuffers(4);
   
   SetIndexStyle(0, DRAW_LINE,0,2);
   SetIndexBuffer(0, Buff_dn);
   SetIndexStyle(1, DRAW_LINE,0,2);
   SetIndexBuffer(1, Buff_up);

   SetIndexBuffer(2, Buff_temp);
   SetIndexBuffer(3, Buff_temp_sig);
   
   short_name = "MACD_line("+FastEMA+","+SlowEMA+","+SignalSMA+")";
	IndicatorShortName(short_name);
   if ( MinBars < 1 ) MinBars = 1;	   
   return (0);
}

int deinit()
{
    int n = ObjectsTotal();
    for (int i = n - 1; i >= 0; i--) 
    {
     string sName = ObjectName(i);
	  if (StringFind(sName, short_name) == 0) 
	  {
	    ObjectDelete(sName);
	  }
    }
	return(0);
}

int start() {
   double sl;
   double atr = iATR(Symbol(), 0, 50, 1);
   
   int limit=Bars-IndicatorCounted();
//---------
   for(int i=Bars-1;i>=0;i--) 
   {
      Buff_temp[i]     =iMACD(NULL,0,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_MAIN,i);
      Buff_temp_sig[i] =iMACD(NULL,0,FastEMA,SlowEMA,SignalSMA,PRICE_CLOSE,MODE_SIGNAL,i);
   }
//---------   
   double value = 0;
   for(i=Bars-1;i>=0;i--) 
   {
     Buff_up[i] = EMPTY_VALUE;
     Buff_dn[i] = EMPTY_VALUE;
     
      if (Buff_temp[i] >= Buff_temp_sig[i]) 
      {
         value -= 0.1;
         Buff_up[i] = value;
         if (Buff_dn[i+1] != EMPTY_VALUE) 
          Buff_up[i+1] = Buff_dn[i+1];
      } 
      else if (Buff_temp[i] < Buff_temp_sig[i])
      {
         value += 0.1;
         Buff_dn[i] = value;
         if (Buff_up[i+1] != EMPTY_VALUE) 
          Buff_dn[i+1] = Buff_up[i+1];
      }
   }
//---------
    if (DrawArrows)
    {
     for(i=Bars-1;i>=0;i--) 
     {
      if(Buff_temp[i]<Buff_temp_sig[i])
      {
       if(Buff_temp[i+1]>Buff_temp_sig[i+1])
       {
        DrawAr("dn",i);    
       }
      }
      if(Buff_temp[i]>Buff_temp_sig[i])
      {
       if(Buff_temp[i+1]<Buff_temp_sig[i+1])
       {
        DrawAr("up",i); 
       }
      }
     }
    } 
//---------  
	int start_i=-1, pre_cross=0, bars, end_bar; 
 	string str_time;
	double change_up, change_dn;
	  
   for (i=BarsCount; i>=0; i--)
	{ 
   if (pre_cross==0)
		{
		 if(Buff_up[i]!=EMPTY_VALUE)
			{
			 pre_cross = 1;
			 start_i = i;
			 continue;
			}
			if( Buff_dn[i]!=EMPTY_VALUE)
			{
			 pre_cross = -1;
			 start_i = i;
			 continue;
			}
		}
		else
		{
		 if((Buff_up[i]!=EMPTY_VALUE && pre_cross<0)|| (Buff_dn[i]!=EMPTY_VALUE && pre_cross>0) || i==0)
			{ 
			 if(start_i-i<= MinBars)
				{
					i ++;
					start_i = -1;
					pre_cross = 0;
					continue;
				}

				end_bar= i+1;

				if(i==0)
				{
				 end_bar= 0;
				}

				change_up = Buff_up[end_bar]-Buff_up[start_i+1];
            change_dn = Buff_dn[end_bar]-Buff_dn[start_i+1];
				str_time	 = TimeToStr(Time[start_i]);

				if(DrawTrendLine)
				{
					if(change_dn>0)
					{
					 trend("_trend_price_" + str_time, 0, Time[start_i+1], Open [start_i+1], Time[end_bar], Open[end_bar], TrendLine_width, TrendLine_style, color_UP);
					}
					if(change_up>0)
					{
					 trend("_trend_price_" + str_time, 0, Time[start_i+1], Open [start_i+1], Time[end_bar], Open[end_bar], TrendLine_width, TrendLine_style, color_DN);
					}
				}
				i ++;
				start_i = -1;
				pre_cross = 0;
			}
		}
	}  
  
//---------   
   if (Buff_temp[0] > Buff_temp_sig[0] && Buff_temp[1] <= Buff_temp_sig[1] && High[0] == Low[0] && High[0] == Close[0] && High[0] == Low[0]) 
   {
      sl = Low[iLowest(Symbol(), 0, MODE_LOW, 4, 0)] - atr / 2.0;
      if (SoundAlerts) Alert("Long " + Symbol() + "! Stop " + DoubleToStr(sl,Digits));
   }
   if (Buff_temp[0] < Buff_temp_sig[0] && Buff_temp[1] >= Buff_temp_sig[1] && High[0] == Low[0] && High[0] == Close[0] && High[0] == Low[0]) 
   {
      sl = High[iHighest(Symbol(), 0, MODE_HIGH, 4, 0)] + atr / 2.0;
      if (SoundAlerts) Alert("Short " + Symbol() + "! Stop " + DoubleToStr(sl,Digits));
   }
   return (0);
}
//----------------------------------------------------
void trend( string name, int window, datetime time1, double level1, datetime time2, double level2, int width, int style, color col )
{
	ObjectDelete	( short_name + name );
	ObjectCreate	( short_name + name, OBJ_TREND, window, time1, level1, time2, level2 );
	ObjectSet		( short_name + name, OBJPROP_COLOR, col );
	ObjectSet		( short_name + name, OBJPROP_RAY, false );
	ObjectSet		( short_name + name, OBJPROP_WIDTH, width );
	ObjectSet		( short_name + name, OBJPROP_STYLE, style );
}
//----------------------------------------------------
void DrawAr(string ssName, int i)
{
    string sName=short_name+" "+ssName+" "+ TimeToStr(Time[i],TIME_DATE|TIME_MINUTES);
    ObjectCreate(sName, OBJ_ARROW, 0, Time[i], 0);
    if(ssName=="up")
    {
    ObjectSet(sName, OBJPROP_ARROWCODE,  225);
    ObjectSet(sName, OBJPROP_PRICE1, Low[i]-5*Point);
    ObjectSet(sName, OBJPROP_COLOR, color_UP);
    }
    if(ssName=="dn")
    {
    ObjectSet(sName, OBJPROP_ARROWCODE,  226);
    ObjectSet(sName, OBJPROP_PRICE1, High[i]+7*Point);
    ObjectSet(sName, OBJPROP_COLOR, color_DN);    
    }    
    ObjectSet(sName, OBJPROP_WIDTH, Arrows_width);
} 