//+------------------------------------------------------------------+
//|                                                    osma-alert.mq4 |
//|  Plots the OsMA (Moving Average of Oscillator) histogram in a      |
//|  separate window and alerts when it crosses its zero line.        |
//|  OsMA = MACD main line - MACD signal line.                        |
//|  Source: web-forex (educational, free to use and modify)          |
//+------------------------------------------------------------------+
#property copyright "web-forex"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 clrDodgerBlue
#property indicator_level1 0

extern int    FastEMA      = 12;
extern int    SlowEMA      = 26;
extern int    SignalSMA    = 9;
extern int    AppliedPrice = PRICE_CLOSE;
extern bool   EnableAlert  = true;
extern bool   EnablePush   = false;

double OsmaBuffer[];

int lastSignal = 0; // 0 = none, 1 = above zero, -1 = below zero

int OnInit()
{
   SetIndexBuffer(0, OsmaBuffer);
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexLabel(0, "OsMA (" + IntegerToString(FastEMA) + "," + IntegerToString(SlowEMA) + "," + IntegerToString(SignalSMA) + ")");

   IndicatorShortName("OsMA Alert (" + IntegerToString(FastEMA) + "," + IntegerToString(SlowEMA) + "," + IntegerToString(SignalSMA) + ")");
   return(INIT_SUCCEEDED);
}

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 start = rates_total - prev_calculated;
   if (start > rates_total - SlowEMA - SignalSMA - 1)
      start = rates_total - SlowEMA - SignalSMA - 1;
   if (start < 0)
      return(rates_total);

   for (int i = start; i >= 0; i--)
      OsmaBuffer[i] = iOsMA(NULL, 0, FastEMA, SlowEMA, SignalSMA, AppliedPrice, i);

   CheckCrossSignal();
   return(rates_total);
}

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

   double osmaPrev = iOsMA(NULL, 0, FastEMA, SlowEMA, SignalSMA, AppliedPrice, 2);
   double osmaLast = iOsMA(NULL, 0, FastEMA, SlowEMA, SignalSMA, AppliedPrice, 1);

   int signal = 0;
   if (osmaPrev <= 0 && osmaLast > 0)
      signal = 1;  // crossed above zero
   else if (osmaPrev >= 0 && osmaLast < 0)
      signal = -1; // crossed below zero

   if (signal != 0 && signal != lastSignal)
   {
      string msg = (signal == 1)
         ? Symbol() + " " + EnumToString((ENUM_TIMEFRAMES)Period()) + ": OsMA crossed above zero"
         : Symbol() + " " + EnumToString((ENUM_TIMEFRAMES)Period()) + ": OsMA crossed below zero";

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

      lastSignal = signal;
   }
}
