FX5_Divergence_v1_1

Author: Copyright � 2007, FX5
Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
FX5_Divergence_v1_1
//+------------------------------------------------------------------+
//|                                               FX5_Divergence.mq4 |
//|                                                              FX5 |
//|                                                    hazem@uk2.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, FX5"
#property link      "hazem@uk2.net"
//----
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_color1 Gold
#property indicator_color2 FireBrick
#property indicator_color3 Green
#property indicator_color4 Red
//---- input parameters
extern string separator1="*** OSMA Settings ***";
extern int    fastEMA=12;
extern int    slowEMA=26;
extern int    signal=9;
extern string separator2="*** Indicator Settings";
extern double positiveSensitivity=0.0001;
extern double negativeSensitivity=-0.0001;
extern double historyBarsCount=0;
extern bool   drawDivergenceLines=true;
//---- buffers
double upOsMA[];
double downOsMA[];
double bullishDivergence[];
double bearishDivergence[];
double OsMA[];
double MACD[];
double Signal[];
static int chartBarsCount;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   IndicatorBuffers(7);
//----   
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(0,upOsMA);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(1,downOsMA);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexBuffer(2,bullishDivergence);
   SetIndexArrow(2,233);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexBuffer(3,bearishDivergence);
   SetIndexArrow(3,234);
   SetIndexStyle(4,DRAW_NONE);
   SetIndexBuffer(4,OsMA);
// additional buffers   
   SetIndexBuffer(5,MACD);
   SetIndexBuffer(6,Signal);
//----   
   SetIndexDrawBegin(0,signal);
   SetIndexDrawBegin(1,signal);
//----   
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);
   IndicatorShortName("FX5_Divergence("+fastEMA+","+slowEMA+
                      ","+signal+")");
//----
   if(historyBarsCount<=0 || historyBarsCount>Bars)
      chartBarsCount=Bars;
   else
      chartBarsCount=historyBarsCount;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   for(int i=ObjectsTotal()-1; i>=0; i--)
     {
      string label=ObjectName(i);
      if(StringSubstr(label,0,14)!="DivergenceLine")
         continue;
      ObjectDelete(label);
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   if(counted_bars==0) limit-=1;
//----
   CalculateOsMA(limit);
   CalculateDivergence(limit,Bars);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateDivergence(int countedBars,int maxind)
  {
   double arrowSeparation=1/MathPow(10,MarketInfo(Symbol(),
                                    MODE_DIGITS)+2)*50;
//----    
   for(int i=countedBars; i>=0; i--)
     {
      bearishDivergence[i]=EMPTY_VALUE;
      bullishDivergence[i]=EMPTY_VALUE;
      //----   
      int firstPeakOrTroughShift=GetFirstPeakOrTrough(i,maxind);
      if(firstPeakOrTroughShift==-1) return;

      double firstPeakOrTroughOsMA=OsMA[firstPeakOrTroughShift];
      if(firstPeakOrTroughOsMA>0)
        {
         int peak_0  =GetIndicatorLastPeak(i,maxind);
         int trough_0=GetIndicatorLastTrough(peak_0,maxind);
         int peak_1  =GetIndicatorLastPeak(trough_0,maxind);
         int trough_1=GetIndicatorLastTrough(peak_1,maxind);
        }
      else
        {
         trough_0=GetIndicatorLastTrough(i,maxind);
         peak_0  =GetIndicatorLastPeak(trough_0,maxind);
         trough_1=GetIndicatorLastTrough(peak_0,maxind);
         peak_1  =GetIndicatorLastPeak(trough_1,maxind);
        }
      //----  
      if(peak_0==-1 || peak_1==-1 || trough_0==-1 || 
         trough_1==-1)
         continue;
      //----          
      double indicatorLastPeak=OsMA[peak_0];
      double indicatorThePeakBefore=OsMA[peak_1];
      double indicatorLastTrough=OsMA[trough_0];
      double indicatorTheTroughBefore=OsMA[trough_1];
/*      
       int pricePeak_0 = GetPriceLastPeak(peak_0);
       int pricePeak_1 = GetPriceLastPeak(peak_1);
       int priceTrough_0 = GetPriceLastTrough(trough_0);
       int priceTrough_1 = GetPriceLastTrough(trough_1);
*/
      int pricePeak_0=peak_0;
      int pricePeak_1=peak_1;
      int priceTrough_0=trough_0;
      int priceTrough_1=trough_1;
      //----
      double priceLastPeak=High[pricePeak_0];
      double priceThePeakBefore=High[pricePeak_1];
      double priceLastTrough=Low[priceTrough_0];
      double priceTheTroughBefore=Low[priceTrough_1];
      // Bearish divergence condition         
      if((priceLastPeak>priceThePeakBefore && 
         indicatorLastPeak<indicatorThePeakBefore) || 
         (priceLastPeak<priceThePeakBefore && 
         indicatorLastPeak>indicatorThePeakBefore))
        {
         bearishDivergence[peak_0]=upOsMA[peak_0]+arrowSeparation;
         if(drawDivergenceLines)
           {
            PriceDrawLine(Time[pricePeak_0],Time[pricePeak_1],
                          priceLastPeak,priceThePeakBefore,Red);
            IndicatorDrawLine(Time[peak_0],Time[peak_1],indicatorLastPeak,
                              indicatorThePeakBefore,Red);
           }
         continue;
        }
      // Bullish divergence condition           
      if((priceLastTrough<priceTheTroughBefore && 
         indicatorLastTrough>indicatorTheTroughBefore) || 
         (priceLastTrough>priceTheTroughBefore && 
         indicatorLastTrough<indicatorTheTroughBefore))
        {
         bullishDivergence[trough_0]=downOsMA[trough_0]-arrowSeparation;
         if(drawDivergenceLines)
           {
            PriceDrawLine(Time[priceTrough_0],Time[priceTrough_1],
                          priceLastTrough,priceTheTroughBefore,Green);
            IndicatorDrawLine(Time[trough_0],Time[trough_1],indicatorLastTrough,
                              indicatorTheTroughBefore,Green);
           }
         continue;
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateOsMA(int countedBars)
  {
   for(int i=countedBars; i>=0; i--)
     {
      MACD[i]=iMA(NULL,0,fastEMA,0,MODE_EMA,PRICE_CLOSE,i) -
              iMA(NULL,0,slowEMA,0,MODE_EMA,PRICE_CLOSE,i);
     }
   for(i=countedBars; i>=0; i--)
     {
      Signal[i]=iMAOnArray(MACD,0,signal,0,MODE_SMA,i);
      OsMA[i]=MACD[i]-Signal[i];
      //----
      if(OsMA[i]>0)
        {
         upOsMA[i]=OsMA[i];
         downOsMA[i]=0;
        }
      else
      if(OsMA[i]<0)
        {
         downOsMA[i]=OsMA[i];
         upOsMA[i]=0;
        }
      else
        {
         upOsMA[i]=0;
         downOsMA[i]=0;
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetPositiveRegionStart(int index,int maxind)
  {
   int regionStart;
   for(int i=index+1; i<maxind-2; i++)
     {
      if(OsMA[i]>=OsMA[i-1] && OsMA[i]>=OsMA[i+1] &&
         OsMA[i]>=OsMA[i+2] && OsMA[i] > positiveSensitivity)
         return(i);
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetNegativeRegionStart(int index,int maxind)
  {
   for(int i=index+1; i<maxind-2; i++)
     {
      if(OsMA[i]<=OsMA[i-1] && OsMA[i]<=OsMA[i+1] &&
         OsMA[i]<=OsMA[i+2] && OsMA[i] < negativeSensitivity)
         return(i);
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetFirstPeakOrTrough(int index,int maxind)
  {
   for(int i=index+1; i<maxind-2; i++)
     {
      if((OsMA[i]>=OsMA[i-1] && OsMA[i]>=OsMA[i+1] && 
         OsMA[i]>=OsMA[i+2] && OsMA[i]>positiveSensitivity) || 
         (OsMA[i]<=OsMA[i-1] && OsMA[i]<=OsMA[i+1] && 
         OsMA[i]<=OsMA[i+2] && OsMA[i]<negativeSensitivity))
         return(i);
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int index,int maxind)
  {
   int regionStart=GetPositiveRegionStart(index,maxind);
   if(regionStart==-1)
      return(-1);
//----   
   int peakShift=0;
   double peakValue=0;
//----
   for(int i=regionStart; i<maxind-2; i++)
     {
      if(OsMA[i]>peakValue && OsMA[i]>=OsMA[i-1] && 
         OsMA[i]>=OsMA[i+1] && OsMA[i]>=OsMA[i+2] && 
         OsMA[i]>positiveSensitivity)
        {
         peakValue=OsMA[i];
         peakShift=i;
        }
      if(OsMA[i]<0)
         break;
     }
   return(peakShift);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int index,int maxind)
  {
   int regionStart=GetNegativeRegionStart(index,maxind);
   if(regionStart==-1)
      return(-1);
//----         
   int troughShift=0;
   double troughValue=0;
//----   
   for(int i=regionStart; i<maxind-2; i++)
     {
      if(OsMA[i]<troughValue && OsMA[i]<=OsMA[i-1] && 
         OsMA[i]<=OsMA[i+1] && OsMA[i]<=OsMA[i+2] && 
         OsMA[i]<negativeSensitivity)
        {
         troughValue=OsMA[i];
         troughShift=i;
        }
      if(OsMA[i]>0)
         break;
     }
   return(troughShift);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PriceDrawLine(datetime x1,datetime x2,double y1,double y2,
                   color lineColor)
  {
   string label="DivergenceLine# "+DoubleToStr(x1,0);
   ObjectDelete(label);
   ObjectCreate(label,OBJ_TREND,0,x1,y1,x2,y2,0,0);
   ObjectSet(label,OBJPROP_RAY,0);
   ObjectSet(label,OBJPROP_COLOR,lineColor);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void IndicatorDrawLine(datetime x1,datetime x2,double y1,double y2,
                       color lineColor)
  {
   int indicatorWindow=WindowFind("FX5_Divergence("+fastEMA+","+
                                  slowEMA+","+signal+")");
   if(indicatorWindow<0)
      return;
//----      
   string label="DivergenceLine$# "+DoubleToStr(x1,0);
   ObjectDelete(label);
   ObjectCreate(label,OBJ_TREND,indicatorWindow,x1,y1,x2,y2,0,0);
   ObjectSet(label,OBJPROP_RAY,0);
   ObjectSet(label,OBJPROP_COLOR,lineColor);
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---