HL_MA_Band_v2

Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
Series array that contains the highest prices of each barSeries array that contains the lowest prices of each bar
Indicators Used
Moving average indicator
0 Views
0 Downloads
0 Favorites
HL_MA_Band_v2
ÿþ//+------------------------------------------------------------------+

//|                                                   HL_MA_Band.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 description "High/Low Moving Average Band indicator\n"

#property description "The indicator draws the band bounded by\ntwo moving averages (for High and Low prices)"

#property indicator_chart_window

#property indicator_buffers 7

#property indicator_plots   3

//--- plot Fill

#property indicator_label1  "Fill"

#property indicator_type1   DRAW_COLOR_HISTOGRAM2

#property indicator_color1  C'179,236,179',C'187,227,194',C'198,218,197',C'241,173,188',C'239,185,192',C'218,197,205',C'209,207,205'

#property indicator_style1  STYLE_SOLID

#property indicator_width1  8

//--- plot UP

#property indicator_label2  "UP"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrRed

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- plot DN

#property indicator_label3  "DN"

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrGreen

#property indicator_style3  STYLE_SOLID

#property indicator_width3  1

//--- enums

enum ENUM_MA_METHOD_EXT

  {

   METHOD_SMA,          // Simple

   METHOD_EMA,          // Exponential

   METHOD_SMMA,         // Smoothed

   METHOD_LWMA,         // Linear-Weighted

   METHOD_WILDER_EMA,   // Wilder Exponential

   METHOD_SINE_WMA,     // Sine-Weighted

   METHOD_TRI_MA,       // Triangular

   METHOD_LSMA,         // Least Square

   METHOD_HMA,          // Hull MA by Alan Hull

   METHOD_ZL_EMA,       // Zero-Lag Exponential

   METHOD_ITREND_MA,    // Instantaneous Trendline by J.Ehlers

   METHOD_MOVING_MEDIAN,// Moving Median

   METHOD_GEO_MEAN,     // Geometric Mean

   METHOD_REMA,         // Regularized EMA by Chris Satchwell

   METHOD_ILRS,         // Integral of Linear Regression Slope

   METHOD_IE_2,         // Combination of LSMA and ILRS

   METHOD_TRI_MA_GEN,   // Triangular MA generalized by J.Ehlers

   METHOD_VWMA          // Volume-Weighted

  };

//--- input parameters

input uint                 InpPeriod   =  20;         // Period

input ENUM_MA_METHOD_EXT   InpMethod   =  METHOD_EMA; // Method

//--- indicator buffers

double         BufferH[];

double         BufferL[];

double         BufferFill1[];

double         BufferFill2[];

double         BufferColors[];

double         BufferPH[];

double         BufferPL[];

//--- global variables

int            period_ma;

int            handle_mah;

int            handle_mal;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- set global variables

   period_ma=int(InpPeriod<1 ? 1 : InpPeriod);

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferFill1,INDICATOR_DATA);

   SetIndexBuffer(1,BufferFill2,INDICATOR_DATA);

   SetIndexBuffer(2,BufferColors,INDICATOR_COLOR_INDEX);

   SetIndexBuffer(3,BufferH,INDICATOR_DATA);

   SetIndexBuffer(4,BufferL,INDICATOR_DATA);

   SetIndexBuffer(5,BufferPH,INDICATOR_CALCULATIONS);

   SetIndexBuffer(6,BufferPL,INDICATOR_CALCULATIONS);

//--- setting indicator parameters

   IndicatorSetString(INDICATOR_SHORTNAME,"High/Low MA Band("+(string)period_ma+")");

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//--- setting plot buffer parameters

   PlotIndexSetString(1,PLOT_LABEL,MethodExtToString(InpMethod)+" High("+string(period_ma)+")");

   PlotIndexSetString(2,PLOT_LABEL,MethodExtToString(InpMethod)+" Low("+string(period_ma)+")");

//--- setting plot buffer parameters

   PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferFill1,true);

   ArraySetAsSeries(BufferFill2,true);

   ArraySetAsSeries(BufferColors,true);

   ArraySetAsSeries(BufferH,true);

   ArraySetAsSeries(BufferL,true);

   ArraySetAsSeries(BufferPH,true);

   ArraySetAsSeries(BufferPL,true);

//--- create handles

   ResetLastError();

   handle_mah=iMA(NULL,PERIOD_CURRENT,1,0,MODE_SMA,PRICE_HIGH);

   if(handle_mah==INVALID_HANDLE)

     {

      Print("The iMA(1) by price High object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

   handle_mal=iMA(NULL,PERIOD_CURRENT,1,0,MODE_SMA,PRICE_LOW);

   if(handle_mal==INVALID_HANDLE)

     {

      Print("The iMA(1) by price Low object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

//---

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

  {

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

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   ArraySetAsSeries(tick_volume,true);

//--- @>25@:0 :>;8G5AB20 4>ABC?=KE 10@>2

   if(rates_total<fmax(period_ma,4)) return 0;

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

   int limit=rates_total-prev_calculated;

   if(limit>1)

     {

      limit=rates_total-3;

      ArrayInitialize(BufferFill1,EMPTY_VALUE);

      ArrayInitialize(BufferFill2,EMPTY_VALUE);

      ArrayInitialize(BufferColors,6);

      ArrayInitialize(BufferH,0);

      ArrayInitialize(BufferL,0);

      ArrayInitialize(BufferPH,0);

      ArrayInitialize(BufferPL,0);

     }

//--- >43>B>2:0 40==KE

   int copied=0,count=(limit==0 ? 1 : rates_total);

   copied=CopyBuffer(handle_mah,0,0,count,BufferPH);

   if(copied!=count) return 0;

   copied=CopyBuffer(handle_mal,0,0,count,BufferPL);

   if(copied!=count) return 0;

   for(int i=limit; i>=0; i--)

     {

      CalculateMA(rates_total,InpMethod,period_ma,i,BufferPH,BufferH,tick_volume);

      CalculateMA(rates_total,InpMethod,period_ma,i,BufferPL,BufferL,tick_volume);

     }

   

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

   for(int i=limit; i>=0; i--)

     {

      BufferFill1[i]=BufferH[i];

      BufferFill2[i]=BufferL[i];

      BufferColors[i]=

        (

         BufferH[i]>BufferH[i+1] && BufferL[i]>BufferL[i+1] ? 0 :

         BufferH[i]>BufferH[i+1] && BufferL[i]<BufferL[i+1] ? 1 :

         BufferH[i]<BufferH[i+1] && BufferL[i]>BufferL[i+1] ? 2 :

         

         BufferL[i]<BufferL[i+1] && BufferH[i]<BufferH[i+1] ? 3 :

         BufferL[i]<BufferL[i+1] && BufferH[i]>BufferH[i+1] ? 4 :

         BufferL[i]>BufferL[i+1] && BufferH[i]<BufferH[i+1] ? 5 : 6

        );

     }

   

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

   return(rates_total);

  }

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

//| GetMA                                                            |

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

template<typename T>

void CalculateMA(const int rates_total,const ENUM_MA_METHOD_EXT method,const int period,const int shift,const double &buffer_price[],double &buffer_ma[],T &tick_volume[])

  {

   switch(method)

     {

      case METHOD_EMA            : buffer_ma[shift] = EMA(rates_total,buffer_price[shift],buffer_ma[shift+1],period,shift);      break;

      case METHOD_SMMA           : buffer_ma[shift] = SMMA(rates_total,buffer_price,buffer_ma[shift+1],period,shift);            break;

      case METHOD_LWMA           : buffer_ma[shift] = LWMA(rates_total,buffer_price,period,shift);                               break;

      case METHOD_WILDER_EMA     : buffer_ma[shift] = Wilder(rates_total,buffer_price[shift],buffer_ma[shift+1],period,shift);   break;

      case METHOD_SINE_WMA       : buffer_ma[shift] = SineWMA(rates_total,buffer_price,period,shift);                            break;

      case METHOD_TRI_MA         : buffer_ma[shift] = TriMA(rates_total,buffer_price,period,shift);                              break;

      case METHOD_LSMA           : buffer_ma[shift] = LSMA(rates_total,buffer_price,period,shift);                               break;

      case METHOD_HMA            : buffer_ma[shift] = HMA(rates_total,buffer_price,period,shift);                                break;

      case METHOD_ZL_EMA         : buffer_ma[shift] = ZeroLagEMA(rates_total,buffer_price,buffer_ma[shift+1],period,shift);      break;

      case METHOD_ITREND_MA      : buffer_ma[shift] = ITrend(rates_total,buffer_price,buffer_ma,period,shift);                   break;

      case METHOD_MOVING_MEDIAN  : buffer_ma[shift] = Median(rates_total,buffer_price,period,shift);                             break;

      case METHOD_GEO_MEAN       : buffer_ma[shift] = GeoMean(rates_total,buffer_price,period,shift);                            break;

      case METHOD_REMA           : buffer_ma[shift] = REMA(rates_total,buffer_price[shift],buffer_ma,period,0.5,shift);          break;

      case METHOD_ILRS           : buffer_ma[shift] = ILRS(rates_total,buffer_price,period,shift);                               break;

      case METHOD_IE_2           : buffer_ma[shift] = IE2(rates_total,buffer_price,period,shift);                                break;

      case METHOD_TRI_MA_GEN     : buffer_ma[shift] = TriMAgen(rates_total,buffer_price,period,shift);                           break;

      case METHOD_VWMA           : buffer_ma[shift] = VWMA(rates_total,buffer_price,tick_volume,period,shift);                   break;

      default /*METHOD_SMA*/     : buffer_ma[shift] = SMA(rates_total,buffer_price,period,shift);                                break;

     }

  }

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

//| Simple Moving Average                                            |

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

double SMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return array_src[shift];

   double sum=0;

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

      sum+=array_src[shift+i];

   return(sum/period);

  }

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

//| Exponential Moving Average                                       |

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

double EMA(const int rates_total,const double price,const double prev,const int period,const int shift)

  {

   return(shift>=rates_total-2 || period<1 ? price : prev+2.0/(1+period)*(price-prev));

  }

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

//| Wilder Exponential Moving Average                                |

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

double Wilder(const int rates_total,const double price,const double prev,const int period,const int shift)

  {

   return(shift>=rates_total-2 || period<1 ? price : prev+(price-prev)/period);

  }

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

//| Linear Weighted Moving Average                                   |

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

double LWMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=0;

   double weight=0;

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

     {

      weight+=(period-i);

      sum+=array_src[shift+i]*(period-i);

     }

   return(weight>0 ? sum/weight : 0);

  }

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

//| Sine Weighted Moving Average                                     |

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

double SineWMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=0;

   double weight=0;

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

     {

      weight+=sin(M_PI*(i+1)/(period+1));

      sum+=array_src[shift+i]*sin(M_PI*(i+1)/(period+1));

     }

   return(weight>0 ? sum/weight : 0);

  }

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

//| Triangular Moving Average                                        |

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

double TriMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sma;

   int len=(int)ceil((period+1)*0.5);

   double sum=0;

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

     {

      sma=SMA(rates_total,array_src,len,shift+i);

      sum+=sma;

     }

   double trima=sum/len;

   return(trima);

  }

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

//| Least Square Moving Average                                      |

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

double LSMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=0;

   for(int i=period; i>=1; i--)

      sum+=(i-(period+1)/3.0)*array_src[shift+period-i];

   double lsma=sum*6.0/(period*(period+1));

   return(lsma);

  }

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

//| Smoothed Moving Average                                          |

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

double SMMA(const int rates_total,const double &array_src[],const double prev,const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double smma=0;

   if(shift==rates_total-period-1)

      smma=SMA(rates_total,array_src,period,shift);

   else if(shift<rates_total-period-1)

     {

      double sum=0;

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

         sum+=array_src[shift+i+1];

      smma=(sum-prev+array_src[shift])/period;

     }

   return smma;

  }

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

//| Hull Moving Average by Alan Hull                                 |

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

double HMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double tmp1[];

   double hma=0;

   int len=(int)sqrt(period);

   ArrayResize(tmp1,len);

   if(shift==rates_total-period-1)

      hma=array_src[shift];

   else if(shift<rates_total-period-1)

     {

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

         tmp1[i]=2.0*LWMA(rates_total,array_src,period/2,shift+i)-LWMA(rates_total,array_src,period,shift+i);

      hma=LWMA(rates_total,tmp1,len,0);

     }

   return hma;

  }

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

//| Zero-Lag Exponential Moving Average                              |

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

double ZeroLagEMA(const int rates_total,const double &array_src[],const double prev,const int period,const int shift)

  {

   double alfa=2.0/(1+period);

   int lag=int(0.5*(period-1));

   return(shift>=rates_total-lag ? array_src[shift] : alfa*(2.0*array_src[shift]-array_src[shift+lag])+(1-alfa)*prev);

  }

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

//| Instantaneous Trendline by J.Ehlers                              |

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

double ITrend(const int rates_total,const double &array_src[],const double &array[],const int period,const int shift)

  {

   double alfa=2.0/(period+1);

   return

     (

      shift<rates_total-7 ?

      (alfa-0.25*alfa*alfa)*array_src[shift]+0.5*alfa*alfa*array_src[shift+1]-(alfa-0.75*alfa*alfa)*array_src[shift+2]+2*(1-alfa)*array[shift+1]-(1-alfa)*(1-alfa)*array[shift+2]:

      (array_src[shift]+2*array_src[shift+1]+array_src[shift+2])/4.0

     );

  }

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

//| Moving Median                                                    |

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

double Median(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<2 || shift>rates_total-period-1)

      return 0;

   double array[];

   ArrayResize(array,period);

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

      array[i]=array_src[shift+i];

   ArraySort(array);

   int num=(int)round((period-1)/2);

   return(fmod(period,2)>0 ? array_src[num] : 0.5*(array_src[num]+array[num+1]));

  }

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

//| Geometric Mean                                                   |

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

double GeoMean(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   double gmean=0;

   if(shift<rates_total-period)

     {

      gmean=pow(array_src[shift],1.0/period);

      for(int i=1; i<period; i++)

         gmean*=pow(array_src[shift+i],1.0/period);

     }

   return(gmean);

  }

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

//| Regularized EMA by Chris Satchwell                               |

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

double REMA(const int rates_total,const double price,const double &array[],const int period,const double lambda,const int shift)

  {

   double alpha=2.0/(period+1);

   return(shift>=rates_total-3 ? price : (array[shift+1]*(1+2*lambda)+alpha*(price-array[shift+1])-lambda*array[shift+2])/(1+lambda));

  }

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

//| Integral of Linear Regression Slope                              |

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

double ILRS(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=period*(period-1)*0.5;

   double sum2=(period-1)*period*(2*period-1)/6.0;

   double sum1=0;

   double sumy=0;

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

     {

      sum1+=i*array_src[shift+i];

      sumy+=array_src[shift+i];

     }

   double num1=period*sum1-sum*sumy;

   double num2=sum*sum-period*sum2;

   double slope=(num2!=0 ? num1/num2 : 0);

   return(slope+SMA(rates_total,array_src,period,shift));

  }

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

//| Combination of LSMA and ILRS                                     |

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

double IE2(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   return(0.5*(ILRS(rates_total,array_src,period,shift)+LSMA(rates_total,array_src,period,shift)));

  }

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

//| Triangular Moving Average generalized by J.Ehlers                |

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

double TriMAgen(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   int len1=(int)floor((period+1)*0.5);

   int len2=(int)ceil((period+1)*0.5);

   double sum=0;

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

      sum+=SMA(rates_total,array_src,len1,shift+i);

   return(sum/len2);

  }

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

//| Volume-Weighted Moving Average                                   |

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

template<typename T>

double VWMA(const int rates_total,const double &array_src[],const T &volume[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=0;

   double weight=0;

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

     {

      weight+=(double)volume[shift+i];

      sum+=array_src[shift+i]*volume[shift+i];

     }

   return(weight>0 ? sum/weight : 0);

  }

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

//| >72@0I05B =08<5=>20=85 <5B>40                                 |

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

string MethodExtToString(ENUM_MA_METHOD_EXT method)

  {

   switch(method)

     {

      case METHOD_EMA            :  return "EMA";

      case METHOD_SMMA           :  return "SMMA";

      case METHOD_LWMA           :  return "LWMA";

      case METHOD_WILDER_EMA     :  return "WMA";

      case METHOD_SINE_WMA       :  return "SinMA";

      case METHOD_TRI_MA         :  return "TriMA";

      case METHOD_LSMA           :  return "LSMA";

      case METHOD_HMA            :  return "HMA";

      case METHOD_ZL_EMA         :  return "ZLMA";

      case METHOD_ITREND_MA      :  return "ITrendMA";

      case METHOD_MOVING_MEDIAN  :  return "Median";

      case METHOD_GEO_MEAN       :  return "GeoMean";

      case METHOD_REMA           :  return "REMA";

      case METHOD_ILRS           :  return "ILRS";

      case METHOD_IE_2           :  return "IE2";

      case METHOD_TRI_MA_GEN     :  return "TriMAgen";

      case METHOD_VWMA           :  return "VWMA";

      default                    :  return "SMA";

     }

  }

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

//| >72@0I05B =08<5=>20=85 F5=K                                     |

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

string PriceToString(ENUM_APPLIED_PRICE price)

  { 

   return StringSubstr(EnumToString(price),6); 

  }

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

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