//+------------------------------------------------------------------
//|
//+------------------------------------------------------------------
#property copyright "mladen"
#property link      "www.forex-station.com"

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1  clrPaleVioletRed
#property indicator_width1  2
#property indicator_level1  0

//
//
//
//
//

extern int                MomentumLength  = 14;              // Momentum length
extern ENUM_APPLIED_PRICE MomentumPrice   = PRICE_CLOSE;     // Momentum price
extern bool               alertsOn        = false;           // Turn alerts on?
extern bool               alertsOnCurrent = false;           // Alerts on still opened bar?
extern bool               alertsMessage   = true;            // Alerts should display message?
extern bool               alertsSound     = false;           // Alerts should play a sound?
extern bool               alertsNotify    = false;           // Alerts should send a notification?
extern bool               alertsEmail     = false;           // Alerts should send an email?
extern string             soundFile       = "alert2.wav";    // Sound file
double momentum[],trend[];

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int init()
{
   for (int i=0; i<indicator_buffers; i++) SetIndexStyle(i,DRAW_LINE);
   IndicatorBuffers(2);
   SetIndexBuffer(0,momentum);
   SetIndexBuffer(1,trend);
   IndicatorShortName("Smoothed momentum ("+(string)MomentumLength+")");
   return(0);
}
int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = MathMin(Bars-counted_bars,Bars-1);
   
   //
   //
   //
   //
   //
   
   for(int i=limit; i>=0; i--) 
   {
      momentum[i] = iMomentumS(iMA(NULL,0,1,0,MODE_SMA,MomentumPrice,i),MomentumLength,1,2,i);
      trend[i] = (i<Bars-1) ? (momentum[i]>0) ? 1 : (momentum[i]<0) ? -1 : trend[i+1] : 0;
   }
   if (alertsOn)
   {
      int whichBar = 1; if (alertsOnCurrent) whichBar = 0; 
      if (trend[whichBar] != trend[whichBar+1])
      {
         if (trend[whichBar] == 1) doAlert(" crossed zero  up");
         if (trend[whichBar] ==-1) doAlert(" crossed zero down");       
      }         
   }
return(0);
}

  
//------------------------------------------------------------------
//                                                                 
//------------------------------------------------------------------
//
//
//
//
//

double workMom[];
double iMomentumS(double price, double length, double powSlow, double powFast, int i)
{
   if (ArraySize(workMom)!=Bars) ArrayResize(workMom,Bars);
      i = Bars-i-1; workMom[i] = price;
      
      //
      //
      //
      //
      //
      
      double suma = 0.0, sumwa=0;
      double sumb = 0.0, sumwb=0;
         for(int k=0; k<length; k++)
         {
            double weight = length-k;
               suma  += workMom[i-k] * MathPow(weight,powSlow);
               sumb  += workMom[i-k] * MathPow(weight,powFast);
               sumwa += MathPow(weight,powSlow);
               sumwb += MathPow(weight,powFast);
         }
   return(sumb/sumwb-suma/sumwa);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" smoothed momentum "+doWhat;
             if (alertsMessage) Alert(message);
             if (alertsNotify)  SendNotification(message);
             if (alertsEmail)   SendMail(_Symbol+" smoothed momentum ",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("");
}