//+------------------------------------------------------------------+
//|                                    MACD_Cross_Signaler 1.0.mq4   |
//|             Copyright © 2009, bluto, http://fxaw.activeboard.com |
//+------------------------------------------------------------------+

#property copyright "Copyright © 2009, bluto"
#property link      "http://fxaw.activeboard.com/"

//---- indicator settings
#property  indicator_chart_window
#property  indicator_buffers 3
#property  indicator_color1 Lime
#property  indicator_color2 Yellow

//---- indicator parameters

extern int  FastEMA = 5;
extern int  SlowEMA = 13;
extern int  MaxBars = 2000;
extern bool Use_DEMAs = true;
extern int  Arrow_Size = 4;
extern bool Enable_Audible_Popup_Alerts = true;

//---- indicator buffers
double      UpArrowBuffer[];
double      DnArrowBuffer[];
double      MacdBuffer[];
color       UpArrowColor = Lime;
color       DnArrowColor = Yellow;
int         Pip_Offset = 10, i = 0, Alert_Count = 0;
double      Adj_Point = 0;
datetime    Prior_Time;
string      mySymbol;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- drawing settings & buffer mappings

   SetIndexBuffer(0,UpArrowBuffer);
   SetIndexStyle(0,DRAW_ARROW,0,Arrow_Size,UpArrowColor); 
   SetIndexLabel(0,"MACD X-Up");
   SetIndexArrow(0,233);
   SetIndexDrawBegin(0,0);
   SetIndexEmptyValue(0,EMPTY_VALUE);
           
   SetIndexBuffer(1,DnArrowBuffer);
   SetIndexStyle(1,DRAW_ARROW,0,Arrow_Size,DnArrowColor); 
   SetIndexLabel(1,"MACD X-Dn");  
   SetIndexArrow(1,234);
   SetIndexDrawBegin(1,0);
   SetIndexEmptyValue(1,EMPTY_VALUE);  
   
   SetIndexBuffer(2,MacdBuffer);
   SetIndexEmptyValue(2,0);
   
   switch(Period()) 
    {
     case 1: 
       Pip_Offset = 10; 
       break;
     case 5: 
       Pip_Offset = 10; 
       break;
     case 15: 
       Pip_Offset = 15; 
       break;
     case 30: 
       Pip_Offset = 20; 
       break;
     case 60: 
       Pip_Offset = 25; 
       break;
     case 240: 
       Pip_Offset = 30; 
       break;
     case 1440: 
       Pip_Offset = 50; 
       break;
     case 10080: 
       Pip_Offset = 100; 
       break;
     case 43200: 
       Pip_Offset = 200; 
       break;      
    } 

  Adj_Point = Point; 
  if (MarketInfo(Symbol(),MODE_DIGITS) == 3 || MarketInfo(Symbol(),MODE_DIGITS) == 5)
   {
    Adj_Point = (Adj_Point * 10);  
   }
   
  mySymbol = StringSubstr(Symbol(),0,6); 

//---- initialization done
   return(0);
  }



int start()
  {
  
// We use a timeclock to keep from executing the logic on every tick call.  Improves performance bigtime.  
  
   if (iTime(Symbol(),Period(),1) != Prior_Time)
    {
     Prior_Time = iTime(Symbol(),Period(),1);
     Alert_Count = 0;
    }
   else
    {
     return;
    }   

// Refresh the MACD buffer array
  
   for (i = MaxBars; i > 0; i--)
    {
     MacdBuffer[i] = MACD(i);
    }

// Loop through and compare MACD array cells to determine where to paint cross-up or cross-down arrows. 
   
   bool is_up = false;
   bool is_dn = false;
                  
   for (i = MaxBars-1; i > 0; i--)
    {
     is_up = false;
     is_dn = false;
         
     if (MacdBuffer[i] > 0 && MacdBuffer[i+1] < 0) 
      {
       UpArrowBuffer[i] = iLow(Symbol(),Period(),i) - Pip_Offset * Adj_Point;
       is_up = true;
      }
     else if (MacdBuffer[i] < 0 && MacdBuffer[i+1] > 0) 
      {
       DnArrowBuffer[i] = iHigh(Symbol(),Period(),i) + Pip_Offset * Adj_Point;
       is_dn = true;
      }
     
     if (Enable_Audible_Popup_Alerts == true && i <= 1 && Alert_Count == 0 && (is_dn || is_up))
      {
       if (is_up)
        {
         Signal_Alert(mySymbol + "  " + tf2txt(Period()) + " :  MACD has crossed up above the zero line",0);
        }
       else
        {
         Signal_Alert(mySymbol + "  " + tf2txt(Period()) + " :  MACD has crossed down below the zero line",0);  
        }
      }   
    } 
      
//---- done
   return(0);
  }
//+------------------------------------------------------------------+

double MACD(int i = 0)
{
	if(Use_DEMAs)
		return(iCustom(NULL,0,"DEMA",FastEMA,0,i) - iCustom(NULL,0,"DEMA",SlowEMA,0,i));
	else
		return(iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i) - iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i));
}

void Signal_Alert(string as_0 = "", int wav_sound = 0)
 {
  Alert(as_0);
  
  if (wav_sound == 0 || wav_sound == 1) {PlaySound("alert.wav");}
  if (wav_sound == 2) {PlaySound("alert2.wav");}
  if (wav_sound == 3) {PlaySound("tick.wav");}
  if (wav_sound == 4) {PlaySound("ok.wav");}
 }
 
 
string tf2txt(int tf)
{
   if (tf == PERIOD_M1)    return("M1");
   if (tf == PERIOD_M5)    return("M5");
   if (tf == PERIOD_M15)    return("M15");
   if (tf == PERIOD_M30)    return("M30");
   if (tf == PERIOD_H1)    return("H1");
   if (tf == PERIOD_H4)    return("H4");
   if (tf == PERIOD_D1)    return("D1");
   if (tf == PERIOD_W1)    return("W1");
   if (tf == PERIOD_MN1)    return("MN1");
   
   return("??");
} 