Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
Series array that contains the highest prices of each barSeries array that contains close prices for each barSeries array that contains open prices of each barSeries array that contains the lowest prices of each barSeries array that contains open time of each bar
0 Views
0 Downloads
0 Favorites
HLBands
ÿþ//+------------------------------------------------------------------+

//|                                                      HLBands.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                                 https://mql5.com |

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

#property copyright "Copyright 2018, MetaQuotes Software Corp."

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

#property version   "1.00"

#property indicator_chart_window

#property indicator_buffers 3

#property indicator_plots   3

//--- plot Band Upper

#property indicator_label1  "Upper"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrCrimson

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot Band Lower

#property indicator_label2  "Lower"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrMediumSlateBlue

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- plot Label day Upper

#property indicator_label3  "Open"

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrLightSteelBlue

#property indicator_style3  STYLE_DOT

#property indicator_width3  1

//--- enums

enum ENUM_CALC_METHOD

  {

   PRICE_HL,            // High/Low

   PRICE_OC             // Open/Close

  };

enum ENUM_MODE_UPDATE

  {

   MODE_UPDATE_OPEN,    // at the opening of the bar

   MODE_UPDATE_ALWAYS   // always

  };

//--- input parameters

input ENUM_TIMEFRAMES   InpTimeframe      =  PERIOD_D1;        // Bands period

input ENUM_MODE_UPDATE  InpBandUpdate     =  MODE_UPDATE_OPEN; // Bands Update

input ENUM_CALC_METHOD  InpBandCalcMethod =  PRICE_HL;         // Bands Applied price

//--- indicator buffers

double         BufferH[];

double         BufferL[];

double         BufferOpen[];

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferH,INDICATOR_DATA);

   SetIndexBuffer(1,BufferL,INDICATOR_DATA);

   SetIndexBuffer(2,BufferOpen,INDICATOR_DATA);

//--- setting a code from the Wingdings charset as the property of PLOT_ARROW

   PlotIndexSetInteger(2,PLOT_ARROW,220);

   PlotIndexSetInteger(2,PLOT_SHOW_DATA,true);

//--- settings indicators parameters

   string tfn=StringSubstr(EnumToString(InpTimeframe),7);

   IndicatorSetString(INDICATOR_SHORTNAME,"High/Low Bands("+tfn+")");

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferH,true);

   ArraySetAsSeries(BufferL,true);

   ArraySetAsSeries(BufferOpen,true);

//---

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

  {

//--- @>25@:0 =0 <8=8<0;L=>5 :>;85AB2> 10@>2 4;O @0AGQB0

   if(rates_total<3) return 0;

//--- #AB0=>2:0 <0AA82>2 1CD5@>2 :0: B09<A5@89

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   ArraySetAsSeries(time,true);

//--- @>25@:0 8 @0AGQB :>;8G5AB20 ?@>AG8BK205<KE 10@>2

   static int index_curr=WRONG_VALUE;

   static int index_prev=WRONG_VALUE;

   static datetime tm=0;

   int limit=rates_total-prev_calculated;

   if(limit>1)

     {

      limit=rates_total-2;

      index_curr=(InpTimeframe<PERIOD_MN1 ? BarShift(Symbol(),InpTimeframe,time[limit]) : BarShift(Symbol(),InpTimeframe,BeginOfYear(time[limit])));

      if(index_curr==WRONG_VALUE) return 0;

      ArrayInitialize(BufferH,EMPTY_VALUE);

      ArrayInitialize(BufferL,EMPTY_VALUE);

      ArrayInitialize(BufferOpen,EMPTY_VALUE);

      BufferH[limit]=(InpBandCalcMethod==PRICE_HL ? high[limit] : fmax(open[limit],close[limit]));

      BufferL[limit]=(InpBandCalcMethod==PRICE_HL ? low[limit]  : fmin(open[limit],close[limit]));

     }

//---  0AGQB 8=48:0B>@0

   for(int i=limit; i>=0 && !IsStopped(); i--)

     {

      index_curr=(InpTimeframe<PERIOD_MN1 ? BarShift(Symbol(),InpTimeframe,time[i]) : BarShift(Symbol(),InpTimeframe,BeginOfYear(time[i])));

      if(index_curr==WRONG_VALUE) return 0;

      static datetime time_bar=0;

      double H=UpperPrice(InpTimeframe,index_curr);

      double L=LowerPrice(InpTimeframe,index_curr);

      //---

      if(index_curr!=index_prev)

        {

         if(index_prev>index_curr)

           {

            time_bar=time[i];

            BufferH[i]=(InpBandUpdate==MODE_UPDATE_OPEN ? (InpBandCalcMethod==PRICE_HL ? high[i] : fmax(open[i],close[i])) : H);

            BufferL[i]=(InpBandUpdate==MODE_UPDATE_OPEN ? (InpBandCalcMethod==PRICE_HL ? low[i]  : fmin(open[i],close[i])) : L);

            BufferOpen[i]=open[i];

           }

         index_prev=index_curr;

        }

      //---

      int bar=BarShift(Symbol(),PERIOD_CURRENT,time_bar);

      if(bar==WRONG_VALUE) continue;

      if(bar==0)

        {

         BufferH[i]=(InpBandCalcMethod==PRICE_HL ? high[i] : fmax(open[i],close[i]));

         BufferL[i]=(InpBandCalcMethod==PRICE_HL ? low[i]  : fmin(open[i],close[i]));

         BufferOpen[i]=open[i];

        }

      else

        {

         BufferH[i]=BufferH[bar];

         BufferL[i]=BufferL[bar];

         BufferOpen[i]=BufferOpen[bar];

         if(InpBandUpdate==MODE_UPDATE_ALWAYS)

           {

            double highest=(InpBandCalcMethod==PRICE_HL ? H : HighestPrice(i,bar,open,close));

            double lowhest=(InpBandCalcMethod==PRICE_HL ? L : LowestPrice(i,bar,open,close));

            SetPrice(highest,i,bar,BufferH);

            SetPrice(lowhest,i,bar,BufferL);

           }

        }

     }

//--- return value of prev_calculated for next call

   return(rates_total);

  }

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

//| >72@0I05B =081>;LHCN F5=C F5?>G:8 10@>2                         |

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

double HighestPrice(const int start,const int end,const double &open[],const double &close[])

  {

   double array[];

   ArraySetAsSeries(array,true);

   int total=(end-start)+1;

   ArrayResize(array,total,20);

   for(int i=0; i<total; i++)

      array[i]=fmax(open[start+i],close[start+i]);

   return array[ArrayMaximum(array)];

  }

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

//| >72@0I05B =08<5=LHCN F5=C F5?>G:8 10@>2                         |

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

double LowestPrice(const int start,const int end,const double &open[],const double &close[])

  {

   double array[];

   ArraySetAsSeries(array,true);

   int total=(end-start)+1;

   ArrayResize(array,total,20);

   for(int i=0; i<total; i++)

      array[i]=fmin(open[start+i],close[start+i]);

   return array[ArrayMinimum(array)];

  }

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

//| #AB0=02;8205B F5=C F5?>G:5 10@>2                                 |

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

void SetPrice(const double price,const int start,const int end,double &buffer[])

  {

   for(int i=start; i<=end; i++)

      buffer[i]=price;

  }

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

//| >72@0I05B 25@E=NN F5=C 10@0                                     |

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

double UpperPrice(ENUM_TIMEFRAMES timeframe,const int index)

  {

   return

   (

    InpBandCalcMethod==PRICE_HL ? High(timeframe,index) :

    (Open(timeframe,index)==0 || Close(timeframe,index)==0 ? 0 : fmax(Open(timeframe,index),Close(timeframe,index)))

    );

  }

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

//| >72@0I05B =86=NN F5=C 10@0                                      |

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

double LowerPrice(ENUM_TIMEFRAMES timeframe,const int index)

  {

   return

   (

    InpBandCalcMethod==PRICE_HL ? Low(timeframe,index) :

    (Open(timeframe,index)==0 || Close(timeframe,index)==0 ? 0 : fmin(Open(timeframe,index),Close(timeframe,index)))

    );

  }

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

//| >72@0I05B A<5I5=85 10@0 ?> 2@5<5=8                              |

//| https://www.mql5.com/ru/code/1864                                |

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

int BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time,bool exact=false)

  {

   datetime last_bar;

   if(!SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar))

     {

      datetime array[1];

      if(CopyTime(symbol_name,timeframe,0,1,array)==1)

         last_bar=array[0];

      else

         return WRONG_VALUE;

     }

   if(time>last_bar)

      return(0);

   int shift=Bars(symbol_name,timeframe,time,last_bar);

   datetime array[1];

   if(CopyTime(symbol_name,timeframe,time,1,array)==1)

      return(array[0]==time ? shift-1 : exact && time>array[0]+PeriodSeconds(timeframe) ? WRONG_VALUE : shift);

   return WRONG_VALUE;

  }

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

//| >72@0I05B 2@5<O C:070==>3> 10@0                                 |

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

datetime Time(const ENUM_TIMEFRAMES timeframe,const int index)

  {

   datetime array[];

   ArraySetAsSeries(array,true);

   if(CopyTime(Symbol(),timeframe,index,1,array)==1) return array[0];

   return 0;

  }

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

//| >72@0I05B Open C:070==>3> 10@0                                  |

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

double Open(const ENUM_TIMEFRAMES timeframe,const int index)

  {

   double array[];

   ArraySetAsSeries(array,true);

   if(CopyOpen(Symbol(),timeframe,index,1,array)==1) return array[0];

   return 0;

  }

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

//| >72@0I05B High C:070==>3> 10@0                                  |

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

double High(const ENUM_TIMEFRAMES timeframe,const int index)

  {

   double array[];

   ArraySetAsSeries(array,true);

   if(CopyHigh(Symbol(),timeframe,index,1,array)==1) return array[0];

   return 0;

  }

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

//| >72@0I05B Low C:070==>3> 10@0                                   |

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

double Low(const ENUM_TIMEFRAMES timeframe,const int index)

  {

   double array[];

   ArraySetAsSeries(array,true);

   if(CopyLow(Symbol(),timeframe,index,1,array)==1) return array[0];

   return 0;

  }

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

//| >72@0I05B Close C:070==>3> 10@0                                 |

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

double Close(const ENUM_TIMEFRAMES timeframe,const int index)

  {

   double array[];

   ArraySetAsSeries(array,true);

   if(CopyClose(Symbol(),timeframe,index,1,array)==1) return array[0];

   return 0;

  }

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

//| >72@0I05B =><5@ 4=O <5AOF0                                      |

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

int TimeDay(const datetime time)

  {

   MqlDateTime tm;

   int day_number=WRONG_VALUE;

   if(TimeToStruct(time,tm))

      day_number=tm.day;

   return day_number;

  }

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

//| >72@0I05B 40BC =0G0;0 3>40 C:070==>9 40BK                       |

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

datetime BeginOfYear(const datetime time)

  {

   MqlDateTime tm;

   if(!TimeToStruct(time,tm)) return WRONG_VALUE;

   tm.mon=1;

   tm.day=1;

   return StructToTime(tm);

  }

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

//| 72@0I05B =08<5=>20=85 B09<D@59<0                               |

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

string NameTimeframe(const ENUM_TIMEFRAMES timeframe)

  {

   return StringSubstr(EnumToString(timeframe),7);

  }

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

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