//+------------------------------------------------------------------+
//|                                    gator-oscillator-alert.mq4      |
//|  Plots the Gator Oscillator (the Alligator's Jaw-Teeth and         |
//|  Teeth-Lips spread, as two histograms) and alerts when both        |
//|  histograms are growing at the same time as the Alligator's        |
//|  Jaw/Teeth/Lips lines are fanned out in order - the "Gator waking   |
//|  up and feeding" signal.                                            |
//|  Source: web-forex (educational, free to use and modify)          |
//+------------------------------------------------------------------+
#property copyright "web-forex"
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 clrLimeGreen
#property indicator_color2 clrOrangeRed
#property indicator_level1 0

extern int  JawPeriod    = 13;
extern int  JawShift     = 8;
extern int  TeethPeriod  = 8;
extern int  TeethShift   = 5;
extern int  LipsPeriod   = 5;
extern int  LipsShift    = 3;
extern int  MAMethod     = MODE_SMMA;
extern int  AppliedPrice = PRICE_MEDIAN;
extern bool EnableAlert  = true;
extern bool EnablePush   = false;

double UpperBuffer[];
double LowerBuffer[];

int lastSignal = 0; // 0 = none, 1 = bullish fan growing, -1 = bearish fan growing

int OnInit()
{
   SetIndexBuffer(0, UpperBuffer);
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexLabel(0, "Gator Upper");

   SetIndexBuffer(1, LowerBuffer);
   SetIndexStyle(1, DRAW_HISTOGRAM);
   SetIndexLabel(1, "Gator Lower");

   IndicatorShortName("Gator Oscillator Alert");
   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 - JawPeriod - JawShift - 1)
      start = rates_total - JawPeriod - JawShift - 1;
   if (start < 0)
      return(rates_total);

   for (int i = start; i >= 0; i--)
   {
      UpperBuffer[i] = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_UPPER, i);
      LowerBuffer[i] = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_LOWER, i);
   }

   CheckGrowSignal();
   return(rates_total);
}

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

   double upperPrev = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_UPPER, 2);
   double upperLast = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_UPPER, 1);
   double lowerPrev = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_LOWER, 2);
   double lowerLast = iGator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_LOWER, 1);

   bool growing = (MathAbs(upperLast) > MathAbs(upperPrev)) && (MathAbs(lowerLast) > MathAbs(lowerPrev));
   if (!growing)
   {
      lastSignal = 0; // reset so the next growing episode can alert again
      return;
   }

   double jaw   = iAlligator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_GATORJAW, 1);
   double teeth = iAlligator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_GATORTEETH, 1);
   double lips  = iAlligator(NULL, 0, JawPeriod, JawShift, TeethPeriod, TeethShift, LipsPeriod, LipsShift, MAMethod, AppliedPrice, MODE_GATORLIPS, 1);

   int signal = 0;
   if (lips > teeth && teeth > jaw)
      signal = 1;  // bullish fan, both Gator histograms growing
   else if (lips < teeth && teeth < jaw)
      signal = -1; // bearish fan, both Gator histograms growing

   if (signal != 0 && signal != lastSignal)
   {
      string msg = (signal == 1)
         ? Symbol() + " " + EnumToString((ENUM_TIMEFRAMES)Period()) + ": Gator waking up (both histograms growing) with a bullish Alligator fan"
         : Symbol() + " " + EnumToString((ENUM_TIMEFRAMES)Period()) + ": Gator waking up (both histograms growing) with a bearish Alligator fan";

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

      lastSignal = signal;
   }
}
