//+------------------------------------------------------------------+
//|                                                    ChMaCross.mq4 |
//|                                             Copyright 2017, MicX |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MicX"
#property link      "https://www.mql5.com"
#property version   "1.02"
#property strict
#property indicator_chart_window

#property indicator_buffers 2
#property indicator_width1 1
#property indicator_width2 1
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrRed

//--- input parameters
input int      ChannelMA = 55;   // Channel MA Period
input int      SignalMA = 33;    // Signal MA Period
input int      ArrowDistance = 30;  // Arrow Distance (point)
input bool     AlertEnable = true; // Enable Alert?
input bool   alertsMessage   = true; // Alert Message (PopUp)?
input bool   alertsEmail     = false; // Alert Email?
input bool   alertsPushNotification = false; //Alert PushNotification?
input bool   alertsSound     = false; // Alert Sound?
input bool   Chart_to_front  = false; // Bring chart to front on alert?

double buy_buf[];
double sell_buf[];

double CHhi, CHlo, CHsig, CHhi2, CHlo2, CHsig2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexArrow(0,233);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,234);
   SetIndexEmptyValue(0,0.0);
   SetIndexEmptyValue(1,0.0);
   SetIndexLabel(0,"Buy");
   SetIndexLabel(1,"Sell");
   SetIndexBuffer(0,buy_buf);
   SetIndexBuffer(1,sell_buf);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
//---
   int limit=rates_total-prev_calculated;
   if(prev_calculated == 0)
      limit -= 2;

//--- main loop 
   for(int i=1; i<=limit; i++) {
      CHhi = iMA(NULL,0,ChannelMA,0,MODE_EMA,PRICE_HIGH,i);
      CHlo = iMA(NULL,0,ChannelMA,0,MODE_EMA,PRICE_LOW,i);
      CHsig = iMA(NULL,0,SignalMA,0,MODE_EMA,PRICE_CLOSE,i);
      CHhi2 = iMA(NULL,0,ChannelMA,0,MODE_EMA,PRICE_HIGH,i+1);
      CHlo2 = iMA(NULL,0,ChannelMA,0,MODE_EMA,PRICE_LOW,i+1);
      CHsig2 = iMA(NULL,0,SignalMA,0,MODE_EMA,PRICE_CLOSE,i+1);
   
      if(CHsig > CHhi && CHsig2 <= CHhi2) {
         buy_buf[i] = low[i] - ArrowDistance * Point;
         if(i == 1 && AlertEnable)
            //Alert(Symbol(), " - Channel Cross BUY Signal");
            doAlert("Channel Cross BUY Signal");
      }
      else if(CHsig < CHlo && CHsig2 >= CHlo2) {
         sell_buf[i] = high[i] + ArrowDistance * Point;
         if(i == 1 && AlertEnable)
            //Alert(Symbol(), " - Channel Cross SELL Signal");
            doAlert("Channel Cross SELL Signal");
      }
      
   } 
   
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

void doAlert(string doWhat)
{
   static string   previousAlert="";
   static datetime previousTime;
   string message;
   
   if (previousAlert!=doWhat || previousTime!=Time[0]) 
   {
      previousAlert = doWhat;
      previousTime  = Time[0];

      //message= StringConcatenate(Symbol()," ",Period(),"M ",TimeToStr(TimeLocal(),TIME_SECONDS),": ",doWhat);
      message= StringConcatenate(Symbol()," ",timeFrameToString(Period())," ",TimeToStr(TimeLocal(),TIME_SECONDS),": ",doWhat);
      
         if (alertsMessage) Alert(message);
         if (Chart_to_front) ChartSetInteger(0,CHART_BRING_TO_TOP,0,true);
         if (alertsEmail)   SendMail(StringConcatenate(Symbol(),"Channel Cross Signal "),message);
         if (alertsPushNotification)
         {
           if(IsTesting()) Print("Message to Push: ",message);
           //Print("Message to Push: ", TimeToStr(Time[0],TIME_DATE|TIME_SECONDS)+" "+DPA);
           //SendNotification(StringConcatenate(TimeToStr(Time[0],TIME_DATE|TIME_SECONDS)," "+DPA));
           SendNotification(StringConcatenate(message));
         } //if (AlertsPushNotification) 
         if (alertsSound)   PlaySound("alert2.wav");
    }
}

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

int stringToTimeFrame(string tfs)
{
   StringToUpper(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+(string)iTfTable[i]) return(iTfTable[i]);
                                                              return(_Period);
}
string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}