
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "www,forex-station.com"
#property link      "www,forex-station.com"

#property indicator_separate_window
#property indicator_buffers 2
#property strict

//
//
//
//
//

extern ENUM_TIMEFRAMES   TimeFrame        = PERIOD_CURRENT;    // Time frame
input int                MaPeriod         = 20;                // Moving average period
input ENUM_MA_METHOD     MaMethod         = MODE_EMA;          // Moving average method
input ENUM_APPLIED_PRICE MaPrice          = PRICE_CLOSE;       // Moving average price
input int                HistoWidth       = 3;                 // Histogram bars width
input color              UpHistoColor     = clrLimeGreen;      // Bullish color
input color              DnHistoColor     = clrRed;            // Bearish color
input bool               alertsOn         = true;              // Alerts on true/false?
input bool               alertsOnCurrent  = false;             // Alerts open bar true/false?
input bool               alertsMessage    = true;              // Alerts message true/false?
input bool               alertsSound      = true;              // Alerts sound true/false?
input bool               alertsNotify     = false;             // Alerts notification true/false?
input bool               alertsEmail      = false;             // Alerts email true/false?
input string             soundfile        = "alert2.wav";      // Sound file to use

double UpH[],DnH[],valc[],count[];
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,MaPeriod,MaMethod,MaPrice,HistoWidth,UpHistoColor,DnHistoColor,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundfile,_buff,_ind)

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int OnInit()
{
   IndicatorBuffers(4);   
   SetIndexBuffer(0,UpH,INDICATOR_DATA); SetIndexStyle(0,DRAW_HISTOGRAM,EMPTY,HistoWidth,UpHistoColor);
   SetIndexBuffer(1,DnH,INDICATOR_DATA); SetIndexStyle(1,DRAW_HISTOGRAM,EMPTY,HistoWidth,DnHistoColor);   
   SetIndexBuffer(2,valc);
   SetIndexBuffer(3,count);
   
   IndicatorSetDouble(INDICATOR_MINIMUM,0);
   IndicatorSetDouble(INDICATOR_MAXIMUM,1);
   
   indicatorFileName = WindowExpertName();
   TimeFrame         = MathMax(TimeFrame,_Period);
     
   IndicatorSetString(INDICATOR_SHORTNAME,timeFrameToString(TimeFrame)+"   Price cross ma");
return(INIT_SUCCEEDED);
}  

void OnDeinit(const int reason){ }

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

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 i=rates_total-prev_calculated+1; if (i>=rates_total) i=rates_total-1; count[0] = i;
      if (TimeFrame!=_Period)
      {
         i = (int)fmax(i,fmin(rates_total-1,_mtfCall(3,0)*TimeFrame/_Period));
         for (; i>=0 && !_StopFlag; i--)
         {
                  int y = iBarShift(NULL,TimeFrame,time[i]);
                     UpH[i] = _mtfCall(0,y);
                     DnH[i] = _mtfCall(1,y);
         }  
   return(rates_total);
   }            
   
   //
   //
   //
   //
   //
           
   for (; i>=0 && !_StopFlag; i--)
   {
      double ma = iMA(NULL,0,MaPeriod,0,MaMethod,MaPrice,i);
      valc[i] = (i<rates_total-1) ? (close[i]>ma) ? 1 : (close[i]<ma) ? -1 : valc[i+1] : 0;
      UpH[i]  = (valc[i] == 1) ? 1 : EMPTY_VALUE;
      DnH[i]  = (valc[i] ==-1) ? 1 : EMPTY_VALUE;             
   }
   manageAlerts();
return(rates_total);
}
      

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

void manageAlerts()
{
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0; 
      if (valc[whichBar]!= valc[whichBar+1])
      {
         static datetime time1 = 0;
         static string   mess1 = "";
            if (valc[whichBar] == 1) doAlert(time1,mess1," up");
            if (valc[whichBar] ==-1) doAlert(time1,mess1," down");
      }
   }
}

//
//
//
//
//

void doAlert(datetime& previousTime, string& previousAlert, string doWhat)
{
   string message;
   
   if (previousAlert != doWhat || previousTime != Time[0]) {
       previousAlert  = doWhat;
       previousTime   = Time[0];

       //
       //
       //
       //
       //

       message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" Price crossing ma "+doWhat;
          if (alertsMessage) Alert(message);
          if (alertsNotify)  SendNotification(message);
          if (alertsEmail)   SendMail(_Symbol+" Price crossing ma ",message);
          if (alertsSound)   PlaySound(soundfile);
   }
}

//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
