/*------------------------------------------------------------------------------------
   Name: x3MA-Trend.mq4
   Copyright ｩ2010, Xaphod, http://forexwhiz.appspot.com
   
   Description: x3MA-Trend 3 MAs line up
	          
   Change log: 
       2010-06-28. Xaphod, v1.00 
          - First Release 
-------------------------------------------------------------------------------------*/
// Indicator properties
#property copyright "Copyright ｩ 2010, Xaphod"
#property link      "http://forexwhiz.appspot.com"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 LimeGreen
#property indicator_color2 Red
#property indicator_color3 Gold
#property indicator_width1  2
#property indicator_width2  2
#property indicator_width3  2
#property indicator_maximum 1
#property indicator_minimum 0

//#include <xDebug.mqh>

// Constant definitions
#define INDICATOR_NAME "x3MA-Trend Histo"
#define INDICATOR_VERSION "v1.00"

// Indicator parameters
extern string    Indi.Copyright= "ｩ2010, forexwhiz.appspot.com";
extern string    Indi.Version= INDICATOR_VERSION;
extern string    MA.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern int       MA.Period1=20;
extern int       MA.Period2=30;
extern int       MA.Period3=60;
extern int       MA.Method=MODE_EMA;
extern int       MA.Price=PRICE_CLOSE;
extern string    TimeFrame.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern int       TimeFrame.TF=0;
extern bool      TimeFrame.Repaint=False;
extern string    Alert.Settings="覧覧覧覧覧覧覧覧覧覧覧覧覧覧覧";
extern bool      Alert.Enable=true;      // Enable Alerts
extern bool      Alert.Popup=false;       // Popup window & sound on alert
extern bool      Alert.Email=false;       // Send email on alert
extern string    Alert.Subject="Default"; // Email Subject. "Default" will result in a preconfigured subject.

// Global module varables
double dMAUp[];
double dMADn[];
double dMACh[];

// Globals
int giRepaintBars;
bool gbInit;

//-----------------------------------------------------------------------------
// function: init()
// Description: Custom indicator initialization function.
//-----------------------------------------------------------------------------
int init() {
  string sTFList;
   
  SetIndexStyle(0,DRAW_HISTOGRAM);
  SetIndexStyle(1,DRAW_HISTOGRAM);
  SetIndexStyle(2,DRAW_HISTOGRAM);
  SetIndexBuffer(0,dMAUp);
  SetIndexBuffer(1,dMADn);
  SetIndexBuffer(2,dMACh);
  SetIndexLabel(0,"Up");
  SetIndexLabel(1,"");
  SetIndexLabel(2,"");
  //for (int i = 0; i < indicator_buffers; i++) SetIndexLabel(i,NULL);
  IndicatorDigits(0);
  if (TimeFrame.TF==0)
    sTFList="["+MA.Period1+","+MA.Period2+","+MA.Period3+"]";
  else
    sTFList="["+TF2Str(TimeFrame.TF)+":"+MA.Period1+","+MA.Period2+","+MA.Period3+"]";
  IndicatorShortName(INDICATOR_NAME+" "+sTFList);
  return(0);
  
  //Init vars
  giRepaintBars=TimeFrame.TF/Period()+2;
  gbInit=True;
}

//-----------------------------------------------------------------------------
// function: deinit()
// Description: Custom indicator deinitialization function.
//-----------------------------------------------------------------------------
int deinit() {
   return (0);
}


///-----------------------------------------------------------------------------
// function: start()
// Description: Custom indicator iteration function.
//-----------------------------------------------------------------------------
int start() {
  int iNewBars;
  int iCountedBars; 
  int i;
  double dMA1,dMA2,dMA3;
  static datetime tCurBar;
  
  // Get unprocessed ticks
  iCountedBars=IndicatorCounted();
  if(iCountedBars < 0) return (-1); 
  if(iCountedBars>0) iCountedBars--;
  iNewBars=Bars-iCountedBars;
  
  // Set bars to redraw
  if (TimeFrame.Repaint && iNewBars<giRepaintBars)
    iNewBars=giRepaintBars;
  
  for(i=iNewBars; i>=0; i--) {
    // Calc MAs for timeframe
    dMA1 = iMA(NULL, TimeFrame.TF, MA.Period1, 0, MA.Method, MA.Price,iBarShift(Symbol(), TimeFrame.TF, Time[i]));
    dMA2 = iMA(NULL, TimeFrame.TF, MA.Period2, 0, MA.Method, MA.Price,iBarShift(Symbol(), TimeFrame.TF, Time[i]));
    dMA3 = iMA(NULL, TimeFrame.TF, MA.Period3, 0, MA.Method, MA.Price,iBarShift(Symbol(), TimeFrame.TF, Time[i]));
    
    // Check MA order and update display
    dMAUp[i] = EMPTY_VALUE;
    dMADn[i] = EMPTY_VALUE;            
    dMACh[i] = EMPTY_VALUE;  
    if (dMA1>dMA2 && dMA2>dMA3 ) 
      dMAUp[i] = 1;
    else if (dMA1<dMA2 && dMA2<dMA3 ) 
      dMADn[i] = 1;
    else
      dMACh[i] = 1;
  }
   
  // Alert on the close of the current bar
  if (Alert.Enable && tCurBar<Time[0] && !gbInit) {
    tCurBar=Time[0];
    if (dMAUp[0]!=EMPTY_VALUE  && dMAUp[1]==EMPTY_VALUE)
      DoAlert(Symbol()+", "+TF2Str(Period()+": MA Trend Up."));
    if (dMADn[0]!=EMPTY_VALUE  && dMADn[1]==EMPTY_VALUE)
      DoAlert(Symbol()+", "+TF2Str(Period()+": MA Trend Up."));
  }

  // Clear the init flag   
  if (gbInit) gbInit=False;
  
  return(0);
}
//+------------------------------------------------------------------+


//-----------------------------------------------------------------------------
// function: DoAlert()
// Description: Signal the popup and email alerts
//-----------------------------------------------------------------------------
void DoAlert(string sAlertMsg) {
  //Popup Alert 
  if (Alert.Popup) 
    Alert(INDICATOR_NAME, sAlertMsg);      
  //Email Alert
  if (Alert.Email) {
    if (Alert.Subject=="Default") Alert.Subject=sAlertMsg;
    SendMail( Alert.Subject, "MT4 Alert!\n"+INDICATOR_NAME+"\n" + TimeToStr(TIME_DATE|TIME_SECONDS )+"\n"+sAlertMsg);          
  }
}


//-----------------------------------------------------------------------------
// function: TF2Str()
// Description: Convert time-frame to a string
//-----------------------------------------------------------------------------
string TF2Str(int iPeriod) {
  switch(iPeriod) {
    case PERIOD_M1: return("M1");
    case PERIOD_M5: return("M5");
    case PERIOD_M15: return("M15");
    case PERIOD_M30: return("M30");
    case PERIOD_H1: return("H1");
    case PERIOD_H4: return("H4");
    case PERIOD_D1: return("D1");
    case PERIOD_W1: return("W1");
    case PERIOD_MN1: return("MN1");
    default: return("M"+iPeriod);
  }
  return(0);
}

 