Author: Copyright 2021, Mitrofanov Nikolay
0 Views
0 Downloads
0 Favorites
RSI_Steps
ÿþ//+------------------------------------------------------------------+

//|                                                      ProjectName |

//|                                      Copyright 2020, CompanyName |

//|                                       http://www.companyname.net |

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

#property copyright "Copyright 2021, Mitrofanov Nikolay"

#property link      "https://www.mql5.com"

#property version   "1.00"

//--- indicator settings

#include <MovingAverages.mqh>



#property indicator_chart_window

#property indicator_buffers 6

#property indicator_plots   1

#property indicator_type1   DRAW_COLOR_LINE

#property indicator_width1  5

//--- input parameters

input int               InpRSIPeriod       = 8;             // rsi period

input double            InpRSILevelUp     = 70.0;           // level up value

input double            InpRSILevelDown   = 30.0;           // level down value

enum MA_METHOD

  {

   None,

   Simple,

   Exponential,

   Smoothed,

   LinearWeighed

  };

input MA_METHOD    InpSmoothMethod      = None;       // type

input int          InpSmoothPeriod       = 4;              // period

input bool InpCrossMiddleEnable = true; // enable crossing 50%

enum ColorScheme

  {

   Different, // All colors are different

   Same // Same color as last color

  };

input ColorScheme InpColorScheme = Different;

input color InpColorExtrenumUP = clrDeepSkyBlue; // Up extrenum

input color InpColorExtrenumDOWN = clrOrange; // Down extrenum

input color InpColorHorizontalLine = clrWhiteSmoke; // Middle place

input color InpColorUPtoDOWN = clrBlue; // Up to down move

input color InpColorDOWNtoUP = clrRed; // Down to up move





enum ExtrenumType {UP, DOWN, RESET};



ExtrenumType lastExtrenum = RESET;



//--- indicator buffers

double    ExtDataBuffer[];

double    ExtRSIBufferSmoothing[];

double    ExtRSIBuffer[];

double    ExtPosBuffer[];

double    ExtNegBuffer[];

double    ExtColorLineBuffer[];

//--- global variable

int       ExtPeriodRSI;

int       ExtSmoothPeriodRSI;



static double p = 0;

static double clr = -1;



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

//| Custom indicator initialization function                         |

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

void OnInit()

  {

//--- check for input

   if(InpRSIPeriod < 1)

     {

      ExtPeriodRSI = 14;

     }

   else

     {

      ExtPeriodRSI = InpRSIPeriod;

     }



   if(InpSmoothPeriod < 1)

     {

      ExtSmoothPeriodRSI = 7;

     }

   else

     {

      ExtSmoothPeriodRSI = InpSmoothPeriod;

     }



//--- indicator buffers mapping



   SetIndexBuffer(0,ExtDataBuffer,INDICATOR_DATA);

   SetIndexBuffer(1,ExtColorLineBuffer,INDICATOR_COLOR_INDEX);

   SetIndexBuffer(2,ExtRSIBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(3,ExtRSIBufferSmoothing,INDICATOR_CALCULATIONS);

   SetIndexBuffer(4,ExtPosBuffer,INDICATOR_CALCULATIONS);

   SetIndexBuffer(5,ExtNegBuffer,INDICATOR_CALCULATIONS);



   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES, 5);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR, 0, InpColorExtrenumUP);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR, 1, InpColorExtrenumDOWN);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR, 2, InpColorHorizontalLine);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR, 3, InpColorUPtoDOWN);

   PlotIndexSetInteger(0,PLOT_LINE_COLOR, 4, InpColorDOWNtoUP);



   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);



   string text="";



   switch(InpSmoothMethod)

     {

      case Exponential:

         text="EMA("+IntegerToString(ExtSmoothPeriodRSI)+")";

         break;

      case Smoothed:

         text="SMMA("+IntegerToString(ExtSmoothPeriodRSI)+")";

         break;

      case LinearWeighed:

         text="LWMA("+IntegerToString(ExtSmoothPeriodRSI)+")";

         break;

      case Simple:

         text="SMA("+IntegerToString(ExtSmoothPeriodRSI)+")";

     }



   IndicatorSetString(INDICATOR_SHORTNAME,"RSI Extrenum Line("+string(ExtPeriodRSI)+") "+text);





//--- initialization done

  }

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

//| Relative Strength Index                                          |

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

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

   double diff;

//--- check for rates count

   if(rates_total<=ExtPeriodRSI)

      return(0);

//--- preliminary calculations

   int pos=prev_calculated-1;

   if(pos<=ExtPeriodRSI)

     {

      //--- first RSIPeriod values of the indicator are not calculated

      ExtRSIBuffer[0]=0.0;

      ExtPosBuffer[0]=0.0;

      ExtNegBuffer[0]=0.0;

      double SumP=0.0;

      double SumN=0.0;

      for(i=1; i<=ExtPeriodRSI; i++)

        {

         ExtRSIBuffer[i]=0.0;

         ExtPosBuffer[i]=0.0;

         ExtNegBuffer[i]=0.0;

         diff=close[i]-close[i-1];

         SumP+=(diff>0?diff:0);

         SumN+=(diff<0?-diff:0);

        }

      //--- calculate first visible value

      ExtPosBuffer[ExtPeriodRSI]=SumP/ExtPeriodRSI;

      ExtNegBuffer[ExtPeriodRSI]=SumN/ExtPeriodRSI;

      if(ExtNegBuffer[ExtPeriodRSI]!=0.0)

         ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));

      else

        {

         if(ExtPosBuffer[ExtPeriodRSI]!=0.0)

            ExtRSIBuffer[ExtPeriodRSI]=100.0;

         else

            ExtRSIBuffer[ExtPeriodRSI]=50.0;

        }

      //--- prepare the position value for main calculation

      pos=ExtPeriodRSI+1;

     }



//--- the main loop of calculations

   for(i=pos; i<rates_total && !IsStopped(); i++)

     {

      diff=close[i]-close[i-1];

      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;

      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;

      if(ExtNegBuffer[i]!=0.0)

         ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);

      else

        {

         if(ExtPosBuffer[i]!=0.0)

            ExtRSIBuffer[i]=100.0;

         else

            ExtRSIBuffer[i]=50.0;

        }

     }







   switch(InpSmoothMethod)

     {

      case None:

         break;

      case Exponential:

         ExponentialMAOnBuffer(rates_total,prev_calculated,0,ExtSmoothPeriodRSI,ExtRSIBuffer,ExtRSIBufferSmoothing);

         break;

      case Smoothed:

         SmoothedMAOnBuffer(rates_total,prev_calculated,0,ExtSmoothPeriodRSI,ExtRSIBuffer,ExtRSIBufferSmoothing); // original

         break;

      case LinearWeighed:

         LinearWeightedMAOnBuffer(rates_total,prev_calculated,0,ExtSmoothPeriodRSI,ExtRSIBuffer,ExtRSIBufferSmoothing);

         break;

      case Simple:

         SimpleMAOnBuffer(rates_total,prev_calculated,0,ExtSmoothPeriodRSI,ExtRSIBuffer,ExtRSIBufferSmoothing);

         break;

     }





   for(i=pos; i<rates_total && !IsStopped(); i++)

     {

      switch(InpSmoothMethod)

        {

         case None:

            eval(ExtRSIBuffer, i, high, low, close, time);

            break;

         default:

            eval(ExtRSIBufferSmoothing, i, high, low, close, time);

            break;

        }

     }





//--- OnCalculate done. Return new prev_calculated.

   return(rates_total);

  }

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





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

//|                                                                  |

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

void eval(double &sourceData[], int indexValue, const double &high[], const double &low[], const double &close[], const datetime &time[])

  {

   if(sourceData[indexValue] >= InpRSILevelUp)

     {

      lastExtrenum = UP;

      clr = 1;

      if(high[indexValue] > high[indexValue-1])

        {

         p = high[indexValue];

        }

      else

        {

         p = high[indexValue-1];

        }

     }

   else

      if(sourceData[indexValue] <= InpRSILevelDown)

        {

         lastExtrenum = DOWN;

         clr = 0;

         if(low[indexValue] < low[indexValue-1])

           {

            p = low[indexValue];

           }

         else

           {

            p = low[indexValue-1];

           }

        }



      else

        {

         if(InpCrossMiddleEnable)

           {

            if(lastExtrenum == UP && sourceData[indexValue-1] > 50 && sourceData[indexValue] < 50)

              {

               clr = 3;

               //p = low[indexValue];

               p = close[indexValue];

               lastExtrenum = RESET;

              }

            else

               if(lastExtrenum == DOWN && sourceData[indexValue-1] < 50 && sourceData[indexValue] > 50)

                 {

                  clr = 4;

                  //p = high[indexValue];

                  p = close[indexValue];

                  lastExtrenum = RESET;

                 }

               else

                 {

                  switch(InpColorScheme)

                    {

                     case Same:

                        clr = ExtColorLineBuffer[indexValue-1];

                        break;

                     case Different:

                        clr = 2;

                        break;

                    }

                 }

           }

         else

           {

            switch(InpColorScheme)

              {

               case Same:

                  clr = ExtColorLineBuffer[indexValue-1];

                  break;

               case Different:

                  clr = 2;

                  break;

              }

           }

        }

   ExtColorLineBuffer[indexValue] = clr;

   ExtDataBuffer[indexValue] = p;



  }





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

//| Indicator deinitialization function                              |

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

void OnDeinit(const int reason)

  {



  }





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

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