Navigation:Home > Content >

normalized_velocity_nrp_mtf_+_divergence_+_alerts_1.01.mq4

Time: 2013-07-28 | Download file:normalized_velocity_nrp_mtf_+_divergence_+_alerts_1.01.mq4

//+------------------------------------------------------------------+

#property link      "www.forex-tsd.com"  
#property copyright "www.forex-tsd.com"

#property indicator_separate_window
#property indicator_minimum    -2
#property indicator_maximum    102
#property indicator_buffers    5
#property indicator_color1     Aqua
#property indicator_color2     Magenta
#property indicator_color3     LimeGreen
#property indicator_color4     Orange
#property indicator_color5     Orange
#property indicator_width3     2
#property indicator_width4     2
#property indicator_width5     2
#property indicator_levelcolor DarkSlateGray

//
//
//
//
//

extern string TimeFrame                 = "Current time frame";
extern int    Length                    = 32;
extern int    NormPeriodRsi             = 14;
extern string _rsitypes                 = "0=rsi,1=wilder rsi,2=rsx,3=cuttler rsi ";
extern int    NormRsiType               = 2; 
extern int    Price                     = PRICE_MEDIAN;
extern int    DivergearrowSize          = 0;
extern bool   drawDivergences           = false;
extern bool   ShowClassicalDivergence   = true;
extern bool   ShowHiddenDivergence      = true;
extern bool   drawIndicatorTrendLines   = true;
extern bool   drawPriceTrendLines       = true;
extern color  divergenceBullishColor    = Lime;
extern color  divergenceBearishColor    = Magenta;
extern string drawLinesIdentificator    = "rsidiverge1";
extern bool   divergenceAlert           = true;
extern bool   divergenceAlertsMessage   = true;
extern bool   divergenceAlertsSound     = true;
extern bool   divergenceAlertsEmail     = false;
extern bool   divergenceAlertsNotify    = false;
extern string divergenceAlertsSoundName = "alert1.wav";
extern bool   alertsOn                  = true;
extern bool   alertsOnCurrent           = false;
extern bool   alertsMessage             = true;
extern bool   alertsSound               = false;
extern bool   alertsNotify              = false;
extern bool   alertsEmail               = false;
extern string soundFile                 = "alert2.wav";
extern bool   Interpolate               = true;

extern double levelOb                   = 80;
extern double levelOs                   = 20;

//
//
//
//
//

double bullishDivergence[];
double bearishDivergence[];
double rsi[];
double rsiDa[];
double rsiDb[];
double slope[];
double trend[];

//
//
//
//
//

string indicatorName;
string labelNames;

string indicatorFileName;
bool   calculateValue;
bool   returnBars;
int    timeFrame;


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
//
//

int init()
{
   IndicatorBuffers(7); 
   SetIndexBuffer(0,bullishDivergence); SetIndexStyle(0,DRAW_ARROW,0,DivergearrowSize); SetIndexArrow(0,233);
   SetIndexBuffer(1,bearishDivergence); SetIndexStyle(1,DRAW_ARROW,0,DivergearrowSize); SetIndexArrow(1,234);  
   SetIndexBuffer(2,rsi); 
   SetIndexBuffer(3,rsiDa);
   SetIndexBuffer(4,rsiDb);
   SetIndexBuffer(5,trend); 
   SetIndexBuffer(6,slope);
   SetLevelValue(0,levelOb);
   SetLevelValue(1,50);
   SetLevelValue(2,levelOs);
   
      //
      //
      //
      //
      //
      
      timeFrame     = stringToTimeFrame(TimeFrame);
      labelNames    = "Norm velocity_DivergenceLine "+drawLinesIdentificator+":";
      indicatorName = timeFrameToString(timeFrame)+" "+getRsiName(NormRsiType)+" normalized velocity";
      IndicatorShortName(indicatorName);
      
      //
      //
      //
      //
      //
      
      indicatorFileName = WindowExpertName();
      calculateValue    = (TimeFrame=="calculateValue"); if (calculateValue) return(0);
      returnBars        = (TimeFrame=="returnBars");     if (returnBars)     return(0);
return (0);
}

//
//
//
//
//

int deinit()
{
   int length=StringLen(labelNames);
   for(int i=ObjectsTotal()-1; i>=0; i--)
   {
      string name = ObjectName(i);
      if(StringSubstr(name,0,length) == labelNames)  ObjectDelete(name);   
   }
   return(0);
}

//
//
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+

int start()
{
   int i,limit,counted_bars=IndicatorCounted();

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = MathMin(Bars-counted_bars,Bars-1);
         if (returnBars)  { bullishDivergence[0] = limit+1; return(0); }
   
   //
   //
   //
   //
   //
   
   if (calculateValue || timeFrame == Period())
   {  
     if (slope[limit]==-1) CleanPoint(limit,rsiDa,rsiDb);   
     
     for(i=limit; i >= 0; i--) 
     {
        double price  = getPrice(Price,i);
        rsi[i]   = iRsi(iVelocity(price,Length,i),NormPeriodRsi,NormRsiType,i);
        rsiDa[i] = EMPTY_VALUE;
        rsiDb[i] = EMPTY_VALUE;
        trend[i] = trend[i+1];
        slope[i] = slope[i+1];
        if (rsi[i]>rsi[i+1]) slope[i] = 1;
        if (rsi[i]levelOb)  trend[i] =-1;
        if (slope[i]==-1) PlotPoint(i,rsiDa,rsiDb,rsi); 
        if (drawDivergences)
        {
          CatchBullishDivergence(i);
          CatchBearishDivergence(i);
        }         
   }
   
   //
   //
   //
   //
   //
      
   if (alertsOn)
   {
      if (alertsOnCurrent)
           int whichBar = 0;
      else     whichBar = 1;
      if (trend[whichBar] != trend[whichBar+1])
      if (trend[whichBar] == 1)
            doAlert("entering oversold");
      else  doAlert("entering overbought");       
   }        
   return(0);           
   }
   
   //
   //
   //
   //
   //
   
   limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period()));
   if (slope[limit]==-1) CleanPoint(limit,rsiDa,rsiDb);
   for(i=limit; i >= 0; i--)  
   {
      int y = iBarShift(NULL,timeFrame,Time[i]);
         rsi[i]               = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Length,NormPeriodRsi,"",NormRsiType,Price,DivergearrowSize,drawDivergences,ShowClassicalDivergence,ShowHiddenDivergence,drawIndicatorTrendLines,drawPriceTrendLines,divergenceBullishColor,divergenceBearishColor,drawLinesIdentificator,divergenceAlert,divergenceAlertsMessage,divergenceAlertsSound,divergenceAlertsEmail,divergenceAlertsNotify,divergenceAlertsSoundName,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,false,2,y);
         trend[i]             = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Length,NormPeriodRsi,"",NormRsiType,Price,DivergearrowSize,drawDivergences,ShowClassicalDivergence,ShowHiddenDivergence,drawIndicatorTrendLines,drawPriceTrendLines,divergenceBullishColor,divergenceBearishColor,drawLinesIdentificator,divergenceAlert,divergenceAlertsMessage,divergenceAlertsSound,divergenceAlertsEmail,divergenceAlertsNotify,divergenceAlertsSoundName,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,false,5,y);
         slope[i]             = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Length,NormPeriodRsi,"",NormRsiType,Price,DivergearrowSize,drawDivergences,ShowClassicalDivergence,ShowHiddenDivergence,drawIndicatorTrendLines,drawPriceTrendLines,divergenceBullishColor,divergenceBearishColor,drawLinesIdentificator,divergenceAlert,divergenceAlertsMessage,divergenceAlertsSound,divergenceAlertsEmail,divergenceAlertsNotify,divergenceAlertsSoundName,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,false,6,y);
         bullishDivergence[i] = EMPTY_VALUE;
         bearishDivergence[i] = EMPTY_VALUE;
         rsiDa[i]             = EMPTY_VALUE;
         rsiDb[i]             = EMPTY_VALUE;
             
      int firstBar = iBarShift(NULL,0,iTime(NULL,timeFrame,y));
      if (i==firstBar)
      {
         bullishDivergence[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Length,NormPeriodRsi,"",NormRsiType,Price,DivergearrowSize,drawDivergences,ShowClassicalDivergence,ShowHiddenDivergence,drawIndicatorTrendLines,drawPriceTrendLines,divergenceBullishColor,divergenceBearishColor,drawLinesIdentificator,divergenceAlert,divergenceAlertsMessage,divergenceAlertsSound,divergenceAlertsEmail,divergenceAlertsNotify,divergenceAlertsSoundName,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,false,0,y);
         bearishDivergence[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Length,NormPeriodRsi,"",NormRsiType,Price,DivergearrowSize,drawDivergences,ShowClassicalDivergence,ShowHiddenDivergence,drawIndicatorTrendLines,drawPriceTrendLines,divergenceBullishColor,divergenceBearishColor,drawLinesIdentificator,divergenceAlert,divergenceAlertsMessage,divergenceAlertsSound,divergenceAlertsEmail,divergenceAlertsNotify,divergenceAlertsSoundName,alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundFile,false,1,y);
      } 
      
      //
      //
      //
      //
      //
      
      if (!Interpolate || y==iBarShift(NULL,timeFrame,Time[i-1])) continue;

      //
      //
      //
      //
      //

      datetime time = iTime(NULL,timeFrame,y);
         for(int n = 1; i+n < Bars && Time[i+n] >= time; n++) continue;	
         for(int k = 1; k < n; k++) rsi[i+k] = rsi[i] + (rsi[i+n] - rsi[i])*k/n;
  }
  for (i=limit;i>=0;i--) if (slope[i]==-1) PlotPoint(i,rsiDa,rsiDb,rsi);
return(0);
}      

//
//
//
//
//

double getPrice(int type, int i)
{
   switch (type)
   {
      case 7:     return((Open[i]+Close[i])/2.0);
      case 8:     return((Open[i]+High[i]+Low[i]+Close[i])/4.0);
      default :   return(iMA(NULL,0,1,0,MODE_SMA,type,i));
   }      
}

//------------------------------------------------------------------
//                                                                  
//------------------------------------------------------------------
//
//
//
//
//
//

string rsiMethodNames[] = {"rsi","Wilders rsi","rsx","Cuttler RSI"};
string getRsiName(int method)
{
   int max = ArraySize(rsiMethodNames)-1;
      method=MathMax(MathMin(method,max),0); return(rsiMethodNames[method]);
}

//
//
//
//
//

double workRsi[][13];
#define _price  0
#define _change 1
#define _changa 2

double iRsi(double price, double period, int rsiMode, int i, int instanceNo=0)
{
   if (ArrayRange(workRsi,0)!=Bars) ArrayResize(workRsi,Bars);
      int z = instanceNo*13; 
      int r = Bars-i-1;
   
   //
   //
   //
   //
   //
   
   workRsi[r][z+_price] = price;
   switch (rsiMode)
   {
      case 0:
         double alpha = 1.0/period; 
         if (r=0; k++) sum += MathAbs(workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]);
                  workRsi[r][z+_change] = (workRsi[r][z+_price]-workRsi[0][z+_price])/MathMax(k,1);
                  workRsi[r][z+_changa] =                                         sum/MathMax(k,1);
            }
         else
            {
               double change = workRsi[r][z+_price]-workRsi[r-1][z+_price];
                               workRsi[r][z+_change] = workRsi[r-1][z+_change] + alpha*(        change  - workRsi[r-1][z+_change]);
                               workRsi[r][z+_changa] = workRsi[r-1][z+_changa] + alpha*(MathAbs(change) - workRsi[r-1][z+_changa]);
            }
         if (workRsi[r][z+_changa] != 0)
               return(50.0*(workRsi[r][z+_change]/workRsi[r][z+_changa]+1));
         else  return(50.0);
         
      //
      //
      //
      //
      //
      
      case 1 :
         workRsi[r][z+1] = iSmma(0.5*(MathAbs(workRsi[r][z+_price]-workRsi[r-1][z+_price])+(workRsi[r][z+_price]-workRsi[r-1][z+_price])),0.5*(period-1),Bars-i-1,instanceNo*2+0);
         workRsi[r][z+2] = iSmma(0.5*(MathAbs(workRsi[r][z+_price]-workRsi[r-1][z+_price])-(workRsi[r][z+_price]-workRsi[r-1][z+_price])),0.5*(period-1),Bars-i-1,instanceNo*2+1);
         if((workRsi[r][z+1] + workRsi[r][z+2]) != 0) 
               return(100.0 * workRsi[r][z+1]/(workRsi[r][z+1] + workRsi[r][z+2]));
         else  return(50);

      //
      //
      //
      //
      //

      case 2 :     
         double Kg = (3.0)/(2.0+period), Hg = 1.0-Kg;
         if (r 0) sump += diff;
               if (diff < 0) sumn -= diff;
         }
         if (sumn > 0)
               return(100.0-100.0/(1.0+sump/sumn));
         else  return(50);
   } 
   return(0);
}

//
//
//
//
//
//

double workSmma[][2];
double iSmma(double price, double period, int r, int instanceNo=0)
{
   if (ArrayRange(workSmma,0)!= Bars) ArrayResize(workSmma,Bars);

   if (r rsi[lastLow] && Low[currentLow] < Low[lastLow])
   {
     if (ShowClassicalDivergence)
     {
        bullishDivergence[currentLow] = rsi[currentLow] - iStdDevOnArray(rsi,0,10,0,MODE_SMA,currentLow);
        if (drawPriceTrendLines)    DrawPriceTrendLine("l",Time[currentLow],Time[lastLow],Low[currentLow],Low[lastLow],    divergenceBullishColor,STYLE_SOLID);
        if (drawIndicatorTrendLines)DrawIndicatorTrendLine("l",Time[currentLow],Time[lastLow],rsi[currentLow],rsi[lastLow],divergenceBullishColor,STYLE_SOLID);
        if (divergenceAlert)        DisplayAlert("Classical bullish divergence",currentLow);  
     }
                        
   }
     
   //
   //
   //
   //
   //
        
   if (rsi[currentLow] < rsi[lastLow] && Low[currentLow] > Low[lastLow])
   {
     if (ShowHiddenDivergence)
     {
        bullishDivergence[currentLow] = rsi[currentLow] - iStdDevOnArray(rsi,0,10,0,MODE_SMA,currentLow);
        if (drawPriceTrendLines)     DrawPriceTrendLine("l",Time[currentLow],Time[lastLow],Low[currentLow],Low[lastLow],    divergenceBullishColor, STYLE_DOT);
        if (drawIndicatorTrendLines) DrawIndicatorTrendLine("l",Time[currentLow],Time[lastLow],rsi[currentLow],rsi[lastLow],divergenceBullishColor, STYLE_DOT);
        if (divergenceAlert)         DisplayAlert("Reverse bullish divergence",currentLow); 
     }
   }
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void CatchBearishDivergence(int shift)
{
   shift++; 
         bearishDivergence[shift] = EMPTY_VALUE;
            ObjectDelete(labelNames+"h"+DoubleToStr(Time[shift],0));
            ObjectDelete(labelNames+"h"+"os" + DoubleToStr(Time[shift],0));            
   if(IsIndicatorPeak(shift) == false) return;
   int currentPeak = shift;
   int lastPeak = GetIndicatorLastPeak(shift+1);

   //
   //
   //
   //
   //
      
   if (rsi[currentPeak] < rsi[lastPeak] && High[currentPeak]>High[lastPeak])
   {
     if (ShowClassicalDivergence)
     {
        bearishDivergence[currentPeak] = rsi[currentPeak] + iStdDevOnArray(rsi,0,10,0,MODE_SMA,currentPeak);
        if (drawPriceTrendLines)     DrawPriceTrendLine("h",Time[currentPeak],Time[lastPeak],High[currentPeak],High[lastPeak],  divergenceBearishColor,STYLE_SOLID);
        if (drawIndicatorTrendLines) DrawIndicatorTrendLine("h",Time[currentPeak],Time[lastPeak],rsi[currentPeak],rsi[lastPeak],divergenceBearishColor,STYLE_SOLID);
        if (divergenceAlert)         DisplayAlert("Classical bearish divergence",currentPeak);
     } 
                        
   }
   
   //
   //
   //
   //
   //

   if (rsi[currentPeak] > rsi[lastPeak] && High[currentPeak] < High[lastPeak])
   {
     if (ShowHiddenDivergence)
     {
        bearishDivergence[currentPeak] = rsi[currentPeak] + iStdDevOnArray(rsi,0,10,0,MODE_SMA,currentPeak);
        if (drawPriceTrendLines)     DrawPriceTrendLine("h",Time[currentPeak],Time[lastPeak],High[currentPeak],High[lastPeak],  divergenceBearishColor, STYLE_DOT);
        if (drawIndicatorTrendLines) DrawIndicatorTrendLine("h",Time[currentPeak],Time[lastPeak],rsi[currentPeak],rsi[lastPeak],divergenceBearishColor, STYLE_DOT);
        if (divergenceAlert)         DisplayAlert("Reverse bearish divergence",currentPeak);
     }
                         
   }   
}

//
//
//
//
//

bool IsIndicatorPeak(int shift)
{
   if(rsi[shift] >= rsi[shift+1] && rsi[shift] > rsi[shift+2] && rsi[shift] > rsi[shift-1])
       return(true);
   else 
       return(false);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

bool IsIndicatorLow(int shift)
{
   if(rsi[shift] <= rsi[shift+1] && rsi[shift] < rsi[shift+2] && rsi[shift] < rsi[shift-1])
       return(true);
   else 
       return(false);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int GetIndicatorLastPeak(int shift)
{
    for(int i = shift+5; i < Bars; i++)
    {
       if(rsi[i] >= rsi[i+1] && rsi[i] > rsi[i+2] && rsi[i] >= rsi[i-1] && rsi[i] > rsi[i-2])
    return(i);
    }
return(-1);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//

int GetIndicatorLastLow(int shift)
{
    for (int i = shift+5; i < Bars; i++)
    {
       if (rsi[i] <= rsi[i+1] && rsi[i] < rsi[i+2] && rsi[i] <= rsi[i-1] && rsi[i] < rsi[i-2])
    return(i);
    }
     
return(-1);
}

//
//
//
//
//

void DisplayAlert(string doWhat, int shift)
{
    string dmessage;
    static datetime lastAlertTime;
    if(shift <= 2 && Time[0] != lastAlertTime)
    {
      dmessage =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," normalized velocity ",doWhat);
          if (divergenceAlertsMessage) Alert(dmessage);
          if (divergenceAlertsNotify)  SendNotification(dmessage);
          if (divergenceAlertsEmail)   SendMail(StringConcatenate(Symbol()," normalized velocity  "),dmessage);
          if (divergenceAlertsSound)   PlaySound(divergenceAlertsSoundName); 
          lastAlertTime = Time[0];
    }
}

//
//
//
//
//

void DrawPriceTrendLine(string first,datetime t1, datetime t2, double p1, double p2, color lineColor, double style)
{
    string label = labelNames+first+"os"+DoubleToStr(t1,0);
      ObjectDelete(label);
      ObjectCreate(label, OBJ_TREND, 0, t1, p1, t2, p2, 0, 0);
         ObjectSet(label, OBJPROP_RAY, 0);
         ObjectSet(label, OBJPROP_COLOR, lineColor);
         ObjectSet(label, OBJPROP_STYLE, style);
}

//
//
//
//
//

void DrawIndicatorTrendLine(string first,datetime t1, datetime t2, double p1, double p2, color lineColor, double style)
{
    int indicatorWindow = WindowFind(indicatorName);
    if (indicatorWindow < 0) return;
    
    //
    //
    //
    //
    //
    
    string label = labelNames+first+DoubleToStr(t1,0);
      ObjectDelete(label);
      ObjectCreate(label, OBJ_TREND, indicatorWindow, t1, p1, t2, p2, 0, 0);
         ObjectSet(label, OBJPROP_RAY, 0);
         ObjectSet(label, OBJPROP_COLOR, lineColor);
         ObjectSet(label, OBJPROP_STYLE, style);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

string sTfTable[] = {"M1","M5","M10","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,10,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   tfs = StringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period()));
                                                      return(Period());
}

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//
//
//
//
//

string StringUpperCase(string str)
{
   string   s = str;
   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int tchar = StringGetChar(s, length);
         if((tchar > 96 && tchar < 123) || (tchar > 223 && tchar < 256))
                     s = StringSetChar(s, length, tchar - 32);
         else if(tchar > -33 && tchar < 0)
                     s = StringSetChar(s, length, tchar + 224);
   }
   return(s);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

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 =  StringConcatenate(Symbol()," ",timeFrameToString(timeFrame)," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," normalized velocity  ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsNotify)  SendNotification(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol()," normalized velocity  "),message);
             if (alertsSound)   PlaySound(soundFile);
      }
}

Recommend