Author: ViDan
DiverStoch
Indicators Used
Stochastic oscillator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
DiverStoch
//+------------------------------------------------------------------+
//|                                                   DiverStoch.mq4 |
//|                                                            ViDan |
//|                                                vi_dancom@mail.ru |
//+------------------------------------------------------------------+
#property copyright "ViDan"
#property link      "vi_dancom@mail.ru"

#property indicator_chart_window
#property indicator_buffers 3

#define arrowsDisplacement 0.0001
extern color  ColorBull = Blue;
extern color  ColorBear = Red;
extern bool   displayAlert = false;//true;
extern bool   English = false;
//---- buffers
//Äëÿ ñòîõàñòèêà
extern int KPeriod = 5;
extern int DPeriod = 3;
extern int Slowing = 3;
double StochLineBuffer[];
double bullishDivergence[];
double bearishDivergence[];
//---- variables
//////
//----
static datetime lastAlertTime;
static string   indicatorName;
static bool b_first = true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   //---- indicators
   SetIndexStyle(0, DRAW_NONE);
   SetIndexBuffer(0, StochLineBuffer);
   SetIndexStyle(1, DRAW_NONE);
   SetIndexBuffer(1, bullishDivergence);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexBuffer(2, bearishDivergence);
   return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
   for(int i = ObjectsTotal() - 1; i >= 0; i--)
     {
       string label = ObjectName(i);
       if(StringSubstr(label, 0, 20) != "Stoch_DivergenceLine")
           continue;
       ObjectDelete(label);   
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   if (b_first)
//Åñëè ïåðâûé çàïóñê - íàéäåì ñòîõàñòèê è îïðåäåëèì åãî ïàðàìåòðû
   {
   string s_parStoch = s_isStoch();
if (s_parStoch !="")
{ 
//   if (s_parStoch =="") 
//   {
//   if (English) Alert ("No Stochastic!   ", Symbol(), " , ", s_GetPeriod (Period()));
//   else Alert ("Íà ãðàôèêå íåò ñòîõàñòèêà!   ", Symbol(), " , ", s_GetPeriod (Period()));
      //return(0);
//   }
 KPeriod = StrToDouble(s_GetPer(s_parStoch, ",",1));
 DPeriod = StrToDouble(s_GetPer(s_parStoch, ",",2));
 Slowing = StrToDouble(s_GetPer(s_parStoch, ",",3));
indicatorName =("Stoch(" + KPeriod+"," + DPeriod + "," + Slowing + ")");
}
b_first = false;
   }
      
   int limit;
   int counted_bars = IndicatorCounted();
   //---- check for possible errors
   if(counted_bars < 0) 
       return(-1);
   //---- last counted bar will be recounted
   if(counted_bars > 0) 
       counted_bars--;
   limit = Bars - counted_bars;
   CalculateIndicator(counted_bars);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateIndicator(int countedBars)
  {
   for(int i = Bars - countedBars; i >= 0; i--)
     {
       CalculateStoch(i);
       CatchBullishDivergence(i + 2);
       CatchBearishDivergence(i + 2);
     }              
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CalculateStoch(int i)
  {
   StochLineBuffer[i] = iStochastic(NULL, 0,KPeriod,DPeriod,Slowing,MODE_SMA,0,MODE_MAIN,i);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBullishDivergence(int shift)
  {
   if(IsIndicatorTrough(shift) == false)
       return;  
   int currentTrough = shift;
   int lastTrough = GetIndicatorLastTrough(shift);
//----   
   if(StochLineBuffer[currentTrough] > StochLineBuffer[lastTrough] && 
      Low[currentTrough] < Low[lastTrough])
     {
       bullishDivergence[currentTrough] = StochLineBuffer[currentTrough] - 
                                          arrowsDisplacement;
       //----
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                             Low[lastTrough], ColorBull, STYLE_SOLID);
       //----
          DrawIndicatorTrendLine(Time[currentTrough], 
                                 Time[lastTrough], 
                                 StochLineBuffer[currentTrough],
                                 StochLineBuffer[lastTrough], 
                                 ColorBull, STYLE_SOLID);
       //----
       if(displayAlert == true)
          if (English) DisplayAlert("Classical bullish divergence on: "+indicatorName+", ", currentTrough);  
          else  DisplayAlert("Êëàññè÷åñêàÿ áû÷üÿ äèâåðãåíöèÿ íà: "+indicatorName+", ", currentTrough);  
     }
//----   
   if(StochLineBuffer[currentTrough] < StochLineBuffer[lastTrough] && 
      Low[currentTrough] > Low[lastTrough])
     {
       bullishDivergence[currentTrough] = StochLineBuffer[currentTrough] - 
                                          arrowsDisplacement;
       //----
           DrawPriceTrendLine(Time[currentTrough], Time[lastTrough], 
                              Low[currentTrough], 
                              Low[lastTrough], ColorBull, STYLE_DOT);
       //----
           DrawIndicatorTrendLine(Time[currentTrough], 
                                  Time[lastTrough], 
                                  StochLineBuffer[currentTrough],
                                  StochLineBuffer[lastTrough], 
                                  ColorBull, STYLE_DOT);
       //----
       if(displayAlert == true)
           if (English)DisplayAlert("Reverse bullish divergence on: "+indicatorName+", ", currentTrough);   
           else DisplayAlert("Îáðàòíàÿ áû÷üÿ äèâåðãåíöèÿ íà: "+indicatorName+", ", currentTrough);   
     }      
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CatchBearishDivergence(int shift)
  {
   if(IsIndicatorPeak(shift) == false)
       return;
   int currentPeak = shift;
   int lastPeak = GetIndicatorLastPeak(shift);
//----   
   if(StochLineBuffer[currentPeak] < StochLineBuffer[lastPeak] && 
      High[currentPeak] > High[lastPeak])
     {
       bearishDivergence[currentPeak] = StochLineBuffer[currentPeak] + 
                                        arrowsDisplacement;
      
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], ColorBear, STYLE_SOLID);
                            
           DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], 
                                  StochLineBuffer[currentPeak],
                                  StochLineBuffer[lastPeak], ColorBear, STYLE_SOLID);

       if(displayAlert == true)
           if (English) DisplayAlert("Classical bearish divergence on: "+indicatorName+", ", currentPeak);  
           else DisplayAlert("Êëàññè÷åñêàÿ ìåäâåæüÿ äèâåðãåíöèÿ íà: "+indicatorName+", ", currentPeak);  
     }
   if(StochLineBuffer[currentPeak] > StochLineBuffer[lastPeak] && 
      High[currentPeak] < High[lastPeak])
     {
       bearishDivergence[currentPeak] = StochLineBuffer[currentPeak] + 
                                        arrowsDisplacement;
       //----
           DrawPriceTrendLine(Time[currentPeak], Time[lastPeak], 
                              High[currentPeak], 
                              High[lastPeak], ColorBear, STYLE_DOT);
       //----
           DrawIndicatorTrendLine(Time[currentPeak], Time[lastPeak], 
                                  StochLineBuffer[currentPeak],
                                  StochLineBuffer[lastPeak], ColorBear, STYLE_DOT);
       //----
       if(displayAlert == true)
           if (English) DisplayAlert("Reverse bearish divergence on: "+indicatorName+", ", currentPeak);   
           else DisplayAlert("Îáðàòíàÿ ìåäâåæüÿ äèâåðãåíöèÿ íà: "+indicatorName+", ", currentPeak);   
        }   
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorPeak(int shift)
  {
   if(StochLineBuffer[shift] >= StochLineBuffer[shift+1] && StochLineBuffer[shift] > StochLineBuffer[shift+2] && 
      StochLineBuffer[shift] > StochLineBuffer[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsIndicatorTrough(int shift)
  {
   if(StochLineBuffer[shift] <= StochLineBuffer[shift+1] && StochLineBuffer[shift] < StochLineBuffer[shift+2] && 
      StochLineBuffer[shift] < StochLineBuffer[shift-1])
       return(true);
   else 
       return(false);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastPeak(int shift)
  {
   for(int i = shift + 5; i < Bars; i++)
     {
         {
           for(int j = i; j < Bars; j++)
             {
               if(StochLineBuffer[j] >= StochLineBuffer[j+1] && StochLineBuffer[j] > StochLineBuffer[j+2] &&
                  StochLineBuffer[j] >= StochLineBuffer[j-1] && StochLineBuffer[j] > StochLineBuffer[j-2])
                   return(j);
             }
         }
     }
   return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetIndicatorLastTrough(int shift)
  {
    for(int i = shift + 5; i < Bars; i++)
      {
          {
            for (int j = i; j < Bars; j++)
              {
                if(StochLineBuffer[j] <= StochLineBuffer[j+1] && StochLineBuffer[j] < StochLineBuffer[j+2] &&
                   StochLineBuffer[j] <= StochLineBuffer[j-1] && StochLineBuffer[j] < StochLineBuffer[j-2])
                    return(j);
              }
          }
      }
    return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DisplayAlert(string message, int shift)
  {
   if(shift <= 2 && Time[shift] != lastAlertTime)
     {
       lastAlertTime = Time[shift];
       Alert(message, Symbol(), " , ", s_GetPeriod (Period()));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawPriceTrendLine(datetime x1, datetime x2, double y1, 
                        double y2, color lineColor, double style)
  {
   string label = "Stoch_DivergenceLine.0# " + 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);
   ObjectSet(label, OBJPROP_STYLE, style);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawIndicatorTrendLine(datetime x1, datetime x2, double y1, 
                            double y2, color lineColor, double style)
  {
   int indicatorWindow = WindowFind(indicatorName);
   if(indicatorWindow < 0)
       return;
   string label = "Stoch_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);
   ObjectSet(label, OBJPROP_STYLE, style);
  }
//+------------------------------------------------------------------+
////Ôóíêöèÿ âîçâðàùàåò ïàðàìåòðû ñòàíäàðòíîãî ñòîõàñòèêà, åñëè îí ïðèñóòñòâóåò íà ãðàôèêå
  string s_isStoch()
 {
    for (int j = 1; j <=34; j++)
    {
      for (int i = 1; i <=13; i++)
      {
         for (int k = 1; k <=13; k++)
         {
          if (WindowFind("Stoch(" + DoubleToStr(j,0)+"," + DoubleToStr(i,0) + "," 
          + DoubleToStr(k,0) + ")") != -1) return(DoubleToStr(j,0)+"," + DoubleToStr(i,0) 
          + "," + DoubleToStr(k,0));
         }
      }
    }
 }
//+------------------------------------------------------------------+
////Âûäåëÿåò ïåðåìåííóþ èç ïåðå÷èñëåíèÿ ñ ðàçäåëèòåëåì razD
string s_GetPer(string s_stRoka, string s_razD,int i_pozPer)
{
string s_vrPer = s_stRoka + s_razD;
string s_mnk1S = "", s_mnk1;
int i_mnk = 0;
for (int j = 0; j <= StringLen(s_vrPer)-1;j++)
  {
s_mnk1 = StringSubstr(s_vrPer, j, 1);
    if (s_mnk1 == s_razD) 
    {
     i_mnk++;
     if (i_mnk < i_pozPer) s_mnk1S = "";
    }
    else
    {
     s_mnk1S = s_mnk1S + s_mnk1;
    }
     if (i_mnk == i_pozPer) return (s_mnk1S);
  }
}

///Âîçâðàùàåò ïåðèîä ãðàôèêà â âèäå ñòðîêè
string s_GetPeriod (int i_per)
{
switch ( i_per )
    {
        case 1:            return("M1 ");
        case 5:            return("M5 ");
        case 15:           return("M15");
        case 30:           return("M30");
        case 60:           return("H1 ");
        case 240:          return("H4 ");
        case 1440:         return("D1 ");
        case 10080:        return("W1 ");
        case 43200:        return("MN1");
    }
}

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 ---