//+------------------------------------------------------------------+
//|                                                momentum-alert.mq5 |
//|  Plots Momentum in a separate window and alerts when it crosses   |
//|  its 100 centerline.                                              |
//|  Source: web-forex (educational, free to use and modify)          |
//+------------------------------------------------------------------+
#property copyright "web-forex"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_label1  "Momentum"
#property indicator_level1  100

input int                MomentumPeriod = 14;
input ENUM_APPLIED_PRICE  AppliedPrice   = PRICE_CLOSE;
input bool                EnableAlert    = true;
input bool                EnablePush     = false;

double MomentumBuffer[];

int momentumHandle = INVALID_HANDLE;
int lastSignal = 0; // 0 = none, 1 = above 100, -1 = below 100

int OnInit()
{
   SetIndexBuffer(0, MomentumBuffer, INDICATOR_DATA);
   ArraySetAsSeries(MomentumBuffer, true);

   momentumHandle = iMomentum(_Symbol, _Period, MomentumPeriod, AppliedPrice);

   IndicatorSetString(INDICATOR_SHORTNAME, "Momentum Alert (" + IntegerToString(MomentumPeriod) + ")");
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   IndicatorRelease(momentumHandle);
}

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[])
{
   if (BarsCalculated(momentumHandle) < rates_total)
      return(0);

   CopyBuffer(momentumHandle, 0, 0, rates_total, MomentumBuffer);

   CheckCrossSignal();
   return(rates_total);
}

void CheckCrossSignal()
{
   if (!EnableAlert && !EnablePush)
      return;

   double arr[];
   ArraySetAsSeries(arr, true);
   if (CopyBuffer(momentumHandle, 0, 0, 3, arr) < 3)
      return;

   double momPrev = arr[2];
   double momLast = arr[1];

   int signal = 0;
   if (momPrev <= 100 && momLast > 100)
      signal = 1;
   else if (momPrev >= 100 && momLast < 100)
      signal = -1;

   if (signal != 0 && signal != lastSignal)
   {
      string msg = (signal == 1)
         ? _Symbol + " " + EnumToString((ENUM_TIMEFRAMES)_Period) + ": Momentum crossed above 100"
         : _Symbol + " " + EnumToString((ENUM_TIMEFRAMES)_Period) + ": Momentum crossed below 100";

      if (EnableAlert)
         Alert(msg);
      if (EnablePush)
         SendNotification(msg);

      lastSignal = signal;
   }
}
