Author: Copyright © 2019, Vladimir Karputov
1 Views
0 Downloads
0 Favorites
BB TREND
ÿþ//+------------------------------------------------------------------+

//|                                                     BB TREND.mq5 |

//|                              Copyright © 2019, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2019, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.000"

#property description "Bollinger Bands Trend"

#include <MovingAverages.mqh>

//---

#property indicator_chart_window

#property indicator_buffers 4

#property indicator_plots   3

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrLightSeaGreen

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrLightSeaGreen

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrLightSeaGreen

#property indicator_label1  "Bands middle"

#property indicator_label2  "Bands upper"

#property indicator_label3  "Bands lower"

//--- input parametrs

input int     InpBandsPeriod=20;       // Period

input int     InpBandsShift=0;         // Shift

input double  InpBandsDeviations=2.0;  // Deviation

input uchar   InpShift=3;              // Shift left point (for trend line's)

//---

input color   InpColor=clrDarkOrchid;  // Trend Line color 

//--- global variables

int           ExtBandsPeriod,ExtBandsShift;

double        ExtBandsDeviations;

int           ExtPlotBegin=0;

//---- indicator buffer

double        ExtMLBuffer[];

double        ExtTLBuffer[];

double        ExtBLBuffer[];

double        ExtStdDevBuffer[];

int           ExtShift=0;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- check for input values

   if(InpBandsPeriod<2)

     {

      ExtBandsPeriod=20;

      printf("Incorrect value for input variable InpBandsPeriod=%d. Indicator will use value=%d for calculations.",InpBandsPeriod,ExtBandsPeriod);

     }

   else ExtBandsPeriod=InpBandsPeriod;

   if(InpBandsShift<0)

     {

      ExtBandsShift=0;

      printf("Incorrect value for input variable InpBandsShift=%d. Indicator will use value=%d for calculations.",InpBandsShift,ExtBandsShift);

     }

   else

      ExtBandsShift=InpBandsShift;

   if(InpBandsDeviations==0.0)

     {

      ExtBandsDeviations=2.0;

      printf("Incorrect value for input variable InpBandsDeviations=%f. Indicator will use value=%f for calculations.",InpBandsDeviations,ExtBandsDeviations);

     }

   else ExtBandsDeviations=InpBandsDeviations;

//--- define buffers

   SetIndexBuffer(0,ExtMLBuffer);

   SetIndexBuffer(1,ExtTLBuffer);

   SetIndexBuffer(2,ExtBLBuffer);

   SetIndexBuffer(3,ExtStdDevBuffer,INDICATOR_CALCULATIONS);

//--- set index labels

   PlotIndexSetString(0,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Middle");

   PlotIndexSetString(1,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Upper");

   PlotIndexSetString(2,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Lower");

//--- indicator name

   IndicatorSetString(INDICATOR_SHORTNAME,"Bollinger Bands");

//--- indexes draw begin settings

   ExtPlotBegin=ExtBandsPeriod-1;

   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtBandsPeriod);

   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtBandsPeriod);

   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtBandsPeriod);

//--- indexes shift settings

   PlotIndexSetInteger(0,PLOT_SHIFT,ExtBandsShift);

   PlotIndexSetInteger(1,PLOT_SHIFT,ExtBandsShift);

   PlotIndexSetInteger(2,PLOT_SHIFT,ExtBandsShift);

//--- number of digits of indicator value

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);

//---

   if(!TrendCreate(0,"BB TREND Middle",0,0,0.0,0,0.0,InpColor) || 

      !TrendCreate(0,"BB TREND Upper",0,0,0.0,0,0.0,InpColor) ||

      !TrendCreate(0,"BB TREND Lower",0,0,0.0,0,0.0,InpColor))

      return(INIT_FAILED);

//---

   ExtShift=(InpShift<2)?1:InpShift;

   ExtShift++;

//---

   return(INIT_SUCCEEDED);

  }

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

//| Custom indicator iteration function                              |

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

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[])

  {

//--- variables

   int pos;

//--- indexes draw begin settings, when we've recieved previous begin

   if(ExtPlotBegin!=ExtBandsPeriod)

     {

      ExtPlotBegin=ExtBandsPeriod;

      PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPlotBegin);

      PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtPlotBegin);

      PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtPlotBegin);

     }

//--- check for bars count

   if(rates_total<ExtPlotBegin)

      return(0);

//--- starting calculation

   if(prev_calculated>1)

      pos=prev_calculated-1;

   else

      pos=0;

//--- main cycle

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

     {

      //--- middle line

      ExtMLBuffer[i]=SimpleMA(i,ExtBandsPeriod,close);

      //--- calculate and write down StdDev

      ExtStdDevBuffer[i]=StdDev_Func(i,close,ExtMLBuffer,ExtBandsPeriod);

      //--- upper line

      ExtTLBuffer[i]=ExtMLBuffer[i]+ExtBandsDeviations*ExtStdDevBuffer[i];

      //--- lower line

      ExtBLBuffer[i]=ExtMLBuffer[i]-ExtBandsDeviations*ExtStdDevBuffer[i];

      //---

     }

//---



   TrendPointChange(0,"BB TREND Middle",0,time[rates_total-ExtShift],ExtMLBuffer[rates_total-ExtShift]);

   TrendPointChange(0,"BB TREND Middle",1,time[rates_total-1],ExtMLBuffer[rates_total-1]);



   TrendPointChange(0,"BB TREND Upper",0,time[rates_total-ExtShift],ExtTLBuffer[rates_total-ExtShift]);

   TrendPointChange(0,"BB TREND Upper",1,time[rates_total-1],ExtTLBuffer[rates_total-1]);



   TrendPointChange(0,"BB TREND Lower",0,time[rates_total-ExtShift],ExtBLBuffer[rates_total-ExtShift]);

   TrendPointChange(0,"BB TREND Lower",1,time[rates_total-1],ExtBLBuffer[rates_total-1]);

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

   return(rates_total);

  }

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

//| Calculate Standard Deviation                                     |

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

double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)

  {

//--- variables

   double StdDev_dTmp=0.0;

//--- check for position

   if(position<period) return(StdDev_dTmp);

//--- calcualte StdDev

   for(int i=0;i<period;i++) StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);

   StdDev_dTmp=MathSqrt(StdDev_dTmp/period);

//--- return calculated value

   return(StdDev_dTmp);

  }

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

//| Create a trend line by the given coordinates                     | 

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

bool TrendCreate(const long            chart_ID=0,        // chart's ID 

                 const string          name="TrendLine",  // line name 

                 const int             sub_window=0,      // subwindow index 

                 datetime              time1=0,           // first point time 

                 double                price1=0,          // first point price 

                 datetime              time2=0,           // second point time 

                 double                price2=0,          // second point price 

                 const color           clr=clrRed,        // line color 

                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style 

                 const int             width=1,           // line width 

                 const bool            back=false,        // in the background 

                 const bool            selection=false,   // highlight to move 

                 const bool            ray_left=false,    // line's continuation to the left 

                 const bool            ray_right=true,    // line's continuation to the right 

                 const bool            hidden=true,       // hidden in the object list 

                 const long            z_order=0)         // priority for mouse click 

  {

//--- set anchor points' coordinates if they are not set 

   ChangeTrendEmptyPoints(time1,price1,time2,price2);

//--- reset the error value 

   ResetLastError();

//--- create a trend line by the given coordinates 

   if(!ObjectCreate(chart_ID,name,OBJ_TREND,sub_window,time1,price1,time2,price2))

     {

      Print(__FUNCTION__,

            ": failed to create a trend line! Error code = ",GetLastError());

      return(false);

     }

//--- set line color 

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set line display style 

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set line width 

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true) 

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the line by mouse 

//--- when creating a graphical object using ObjectCreate function, the object cannot be 

//--- highlighted and moved by default. Inside this method, selection parameter 

//--- is true by default making it possible to highlight and move the object 

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- enable (true) or disable (false) the mode of continuation of the line's display to the left 

   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);

//--- enable (true) or disable (false) the mode of continuation of the line's display to the right 

   ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);

//--- hide (true) or display (false) graphical object name in the object list 

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart 

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution 

   return(true);

  }

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

//| Move trend line anchor point                                     | 

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

bool TrendPointChange(const long   chart_ID=0,       // chart's ID 

                      const string name="TrendLine", // line name 

                      const int    point_index=0,    // anchor point index 

                      datetime     time=0,           // anchor point time coordinate 

                      double       price=0)          // anchor point price coordinate 

  {

//--- if point position is not set, move it to the current bar having Bid price 

   if(!time)

      time=TimeCurrent();

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value 

   ResetLastError();

//--- move trend line's anchor point 

   if(!ObjectMove(chart_ID,name,point_index,time,price))

     {

      Print(__FUNCTION__,

            ": failed to move the anchor point! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

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

//| Check the values of trend line's anchor points and set default   | 

//| values for empty ones                                            | 

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

void ChangeTrendEmptyPoints(datetime &time1,double &price1,

                            datetime &time2,double &price2)

  {

//--- if the first point's time is not set, it will be on the current bar 

   if(!time1)

      time1=TimeCurrent();

//--- if the first point's price is not set, it will have Bid value 

   if(!price1)

      price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- if the second point's time is not set, it is located 9 bars left from the second one 

   if(!time2)

     {

      //--- array for receiving the open time of the last 10 bars 

      datetime temp[10];

      CopyTime(Symbol(),Period(),time1,10,temp);

      //--- set the second point 9 bars left from the first one 

      time2=temp[0];

     }

//--- if the second point's price is not set, it is equal to the first point's one 

   if(!price2)

      price2=price1;

  }

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

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