MTF_ATR_Channel

Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
Series array that contains open time of each barSeries array that contains tick volumes of each bar
Indicators Used
Moving average indicatorIndicator of the average true range
0 Views
0 Downloads
0 Favorites
MTF_ATR_Channel
ÿþ//+------------------------------------------------------------------+

//|                                              MTF_ATR_Channel.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 "Multi Time Frame ATR Channel indicator"

#property indicator_chart_window

#property indicator_buffers 17

#property indicator_plots   7

//--- plot Top3

#property indicator_label1  "Top3"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrDarkRed

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot Top2

#property indicator_label2  "Top2"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrRed

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- plot Top1

#property indicator_label3  "Top1"

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrOrange

#property indicator_style3  STYLE_SOLID

#property indicator_width3  1

//--- plot MA

#property indicator_label4  "MA"

#property indicator_type4   DRAW_LINE

#property indicator_color4  clrDodgerBlue

#property indicator_style4  STYLE_SOLID

#property indicator_width4  1

//--- plot Bottom1

#property indicator_label5  "Bottom1"

#property indicator_type5   DRAW_LINE

#property indicator_color5  clrLimeGreen

#property indicator_style5  STYLE_SOLID

#property indicator_width5  1

//--- plot Bottom2

#property indicator_label6  "Bottom2"

#property indicator_type6   DRAW_LINE

#property indicator_color6  clrGreen

#property indicator_style6  STYLE_SOLID

#property indicator_width6  1

//--- plot Bottom3

#property indicator_label7  "Bottom3"

#property indicator_type7   DRAW_LINE

#property indicator_color7  clrDarkGreen

#property indicator_style7  STYLE_SOLID

#property indicator_width7  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

  };

//---

enum ENUM_DRAW_MODE

  {

   DRAW_MODE_STEPS,  // Steps

   DRAW_MODE_SLOPE   // Slope

  };

//---

enum ENUM_INPUT_YES_NO

  {

   INPUT_YES   =  1,    // Yes

   INPUT_NO    =  0     // No

  };

//--- input parameters

input uint                 InpPeriodATR      =  10;               // ATR period

input uint                 InpPeriodMA       =  20;               // MA period

input ENUM_MA_METHOD_EXT   InpMethodMA       =  METHOD_SMA;       // MA method

input ENUM_APPLIED_PRICE   InpAppliedPrice   =  PRICE_CLOSE;      // MA applied price

input double               InpMultiplier     =  1.0;              // ATR multiplier

input ENUM_TIMEFRAMES      InpTimeframe      =  PERIOD_CURRENT;   // Timeframe

input ENUM_DRAW_MODE       InpDrawMode       =  DRAW_MODE_SLOPE;  // Drawing mode

//--- indicator buffers

double         BufferTop3[];

double         BufferTop2[];

double         BufferTop1[];

double         BufferMA[];

double         BufferBottom1[];

double         BufferBottom2[];

double         BufferBottom3[];

double         BufferTop3tmp[];

double         BufferTop2tmp[];

double         BufferTop1tmp[];

double         BufferMAtmp[];

double         BufferBottom1tmp[];

double         BufferBottom2tmp[];

double         BufferBottom3tmp[];

double         BufferPrice[];

double         BufferATR[];

double         BufferVol[];

//--- global variables

ENUM_TIMEFRAMES   timeframe1;

double            multiplier;

int               period_ma;

int               period_atr;

int               period_max;

int               handle_ma;

int               handle_atr;

int               handle_vol;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- timer

   EventSetTimer(90);

//--- set global variables

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

   timeframe1=(InpTimeframe>Period() ? InpTimeframe : Period());

   period_atr=int(InpPeriodATR<1 ? 1 : InpPeriodATR);

   period_max=fmax(period_ma,period_atr);

   multiplier=InpMultiplier;

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferTop3,INDICATOR_DATA);

   SetIndexBuffer(1,BufferTop2,INDICATOR_DATA);

   SetIndexBuffer(2,BufferTop1,INDICATOR_DATA);

   SetIndexBuffer(3,BufferMA,INDICATOR_DATA);

   SetIndexBuffer(4,BufferBottom1,INDICATOR_DATA);

   SetIndexBuffer(5,BufferBottom2,INDICATOR_DATA);

   SetIndexBuffer(6,BufferBottom3,INDICATOR_DATA);

   SetIndexBuffer(7,BufferTop3tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(8,BufferTop2tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(9,BufferTop1tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(10,BufferMAtmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(11,BufferBottom1tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(12,BufferBottom2tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(13,BufferBottom3tmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(14,BufferPrice,INDICATOR_CALCULATIONS);

   SetIndexBuffer(15,BufferATR,INDICATOR_CALCULATIONS);

   SetIndexBuffer(16,BufferVol,INDICATOR_CALCULATIONS);

//--- setting indicator parameters

   string label=TimeframeToString(timeframe1)+" ATR Channel("+(string)period_atr+","+(string)period_ma+","+DoubleToString(multiplier,1)+")";

   IndicatorSetString(INDICATOR_SHORTNAME,label);

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//--- setting plot buffer parameters

   PlotIndexSetString(0,PLOT_LABEL,TimeframeToString(timeframe1)+" Top3("+(string)period_atr+")");

   PlotIndexSetString(1,PLOT_LABEL,TimeframeToString(timeframe1)+" Top2("+(string)period_atr+")");

   PlotIndexSetString(2,PLOT_LABEL,TimeframeToString(timeframe1)+" Top1("+(string)period_atr+")");

   PlotIndexSetString(3,PLOT_LABEL,TimeframeToString(timeframe1)+" MA("+(string)period_ma+")");

   PlotIndexSetString(4,PLOT_LABEL,TimeframeToString(timeframe1)+" Bottom1("+(string)period_atr+")");

   PlotIndexSetString(5,PLOT_LABEL,TimeframeToString(timeframe1)+" Bottom2("+(string)period_atr+")");

   PlotIndexSetString(6,PLOT_LABEL,TimeframeToString(timeframe1)+" Bottom3("+(string)period_atr+")");

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferTop3,true);

   ArraySetAsSeries(BufferTop2,true);

   ArraySetAsSeries(BufferTop1,true);

   ArraySetAsSeries(BufferMA,true);

   ArraySetAsSeries(BufferBottom1,true);

   ArraySetAsSeries(BufferBottom2,true);

   ArraySetAsSeries(BufferBottom3,true);

   ArraySetAsSeries(BufferTop3tmp,true);

   ArraySetAsSeries(BufferTop2tmp,true);

   ArraySetAsSeries(BufferTop1tmp,true);

   ArraySetAsSeries(BufferMAtmp,true);

   ArraySetAsSeries(BufferBottom1tmp,true);

   ArraySetAsSeries(BufferBottom2tmp,true);

   ArraySetAsSeries(BufferBottom3tmp,true);

   ArraySetAsSeries(BufferPrice,true);

   ArraySetAsSeries(BufferATR,true);

   ArraySetAsSeries(BufferVol,true);

//--- create handles

   ResetLastError();

   handle_ma=iMA(NULL,timeframe1,1,0,MODE_SMA,InpAppliedPrice);

   if(handle_ma==INVALID_HANDLE)

     {

      Print("The ",TimeframeToString(timeframe1)," iMA(1) object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

   handle_atr=iATR(NULL,timeframe1,period_atr);

   if(handle_atr==INVALID_HANDLE)

     {

      Print("The ",TimeframeToString(timeframe1)," iATR(",(string)period_atr,") object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

   handle_vol=iVolumes(NULL,timeframe1,VOLUME_TICK);

   if(handle_vol==INVALID_HANDLE)

     {

      Print("The iVolumes(VOLUME_TICK) object was not created: Error ",GetLastError());

      return INIT_FAILED;

     }

//--- get timeframe

   Time(NULL,timeframe1,1);

//---

   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 :>;8G5AB20 4>ABC?=KE 10@>2

   if(rates_total<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(BufferTop3,EMPTY_VALUE);

      ArrayInitialize(BufferTop2,EMPTY_VALUE);

      ArrayInitialize(BufferTop1,EMPTY_VALUE);

      ArrayInitialize(BufferMA,EMPTY_VALUE);

      ArrayInitialize(BufferBottom1,EMPTY_VALUE);

      ArrayInitialize(BufferBottom2,EMPTY_VALUE);

      ArrayInitialize(BufferBottom3,EMPTY_VALUE);

      ArrayInitialize(BufferTop3tmp,0);

      ArrayInitialize(BufferTop2tmp,0);

      ArrayInitialize(BufferTop1tmp,0);

      ArrayInitialize(BufferMAtmp,0);

      ArrayInitialize(BufferBottom1tmp,0);

      ArrayInitialize(BufferBottom2tmp,0);

      ArrayInitialize(BufferBottom3tmp,0);

      ArrayInitialize(BufferPrice,0);

      ArrayInitialize(BufferATR,0);

      ArrayInitialize(BufferVol,0);

     }

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

   if(Time(NULL,timeframe1,1)==0)

      return 0;

   int bars=(timeframe1==Period() ? rates_total : Bars(NULL,timeframe1));

   

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

   copied=CopyBuffer(handle_atr,0,0,count,BufferATR);

   if(copied!=count) return 0;

   copied=CopyBuffer(handle_vol,0,0,count,BufferVol);

   if(copied!=count) return 0;

   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);

   if(copied!=count) return 0;

   

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

     {

      CalculateMA(fmin(bars,rates_total),InpMethodMA,period_ma,i,BufferPrice,BufferMAtmp,BufferVol);

      BufferTop1tmp[i]=BufferMAtmp[i]+(BufferATR[i]*multiplier);

      BufferTop2tmp[i]=BufferMAtmp[i]+(BufferATR[i]*multiplier*2.0);

      BufferTop3tmp[i]=BufferMAtmp[i]+(BufferATR[i]*multiplier*3.0);

      BufferBottom1tmp[i]=BufferMAtmp[i]-(BufferATR[i]*multiplier);

      BufferBottom2tmp[i]=BufferMAtmp[i]-(BufferATR[i]*multiplier*2.0);

      BufferBottom3tmp[i]=BufferMAtmp[i]-(BufferATR[i]*multiplier*3.0);

     }



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

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

     {

      DataConversion(rates_total,NULL,timeframe1,i,BufferTop1tmp,BufferTop1,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferTop2tmp,BufferTop2,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferTop3tmp,BufferTop3,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferMAtmp,BufferMA,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferBottom1tmp,BufferBottom1,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferBottom2tmp,BufferBottom2,InpDrawMode);

      DataConversion(rates_total,NULL,timeframe1,i,BufferBottom3tmp,BufferBottom3,InpDrawMode);

     }

   

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

   return(rates_total);

  }

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

//| Custom indicator timer function                                  |

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

void OnTimer()

  {

   if(timeframe1==Period())

      return;

   Time(NULL,timeframe1,1);

  }  

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

//| Transfering data from the source timeframe to current timeframe  |

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

void DataConversion(const int rates_total,

                    const string symbol_name,

                    const ENUM_TIMEFRAMES timeframe_src,

                    const int shift,

                    const double &buffer_src[],

                    double &buffer_dest[],

                    ENUM_DRAW_MODE mode=DRAW_MODE_STEPS

                   )

  {

   if(timeframe_src==Period())

     {

      buffer_dest[shift]=buffer_src[shift];

      return;

     }

   int bar_curr=BarToCurrent(symbol_name,timeframe_src,shift);

   if(bar_curr>rates_total-1)

      return;

   int bar_prev=BarToCurrent(symbol_name,timeframe_src,shift+1);

   int bar_next=(shift>0 ? BarToCurrent(symbol_name,timeframe_src,shift-1) : 0);

   if(bar_prev==WRONG_VALUE || bar_curr==WRONG_VALUE || bar_next==WRONG_VALUE)

      return;

   buffer_dest[bar_curr]=buffer_src[shift];

   if(mode==DRAW_MODE_STEPS)

      for(int j=bar_curr; j>=bar_next; j--)

         buffer_dest[j]=buffer_dest[bar_curr];

   else

     {

      if(bar_prev>rates_total-1) return;

      for(int j=bar_prev; j>=bar_curr; j--)

         buffer_dest[j]=EquationDirect(bar_prev,buffer_dest[bar_prev],bar_curr,buffer_dest[bar_curr],j);

      if(shift==0)

         for(int j=bar_curr; j>=0; j--)

            buffer_dest[j]=buffer_dest[bar_curr];

     }

  }

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

//| >72@0I05B 10@ 7040==>3> B09<D@59<0 :0: 10@ B5:CI53> B09<D@59<0  |

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

int BarToCurrent(const string symbol_name,const ENUM_TIMEFRAMES timeframe_src,const int shift,bool exact=false)

  {

   datetime time=Time(symbol_name,timeframe_src,shift);

   return(time!=0 ? BarShift(symbol_name,Period(),time,exact) : WRONG_VALUE);

  }  

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

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

//| https://www.mql5.com/ru/forum/743/page11#comment_7010041         |

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

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

  {

   int res=Bars(symbol_name,timeframe,time+1,UINT_MAX);

   if(exact) if((timeframe!=PERIOD_MN1 || time>TimeCurrent()) && res==Bars(symbol_name,timeframe,time-PeriodSeconds(timeframe)+1,UINT_MAX)) return(WRONG_VALUE);

   return res;

  }

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

//| >72@0I05B Time                                                  |

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

datetime Time(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)

  {

   datetime array[];

   ArraySetAsSeries(array,true);

   return(CopyTime(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);

  }

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

//| >72@0I05B Volume                                                |

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

long Volume(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)

  {

   long array[];

   ArraySetAsSeries(array,true);

   return(CopyTickVolume(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);

  }

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

//| #@02=5=85 ?@O<>9                                                 |

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

double EquationDirect(const int left_bar,const double left_price,const int right_bar,const double right_price,const int bar_to_search) 

  {

   return(right_bar==left_bar ? left_price : (right_price-left_price)/(right_bar-left_bar)*(bar_to_search-left_bar)+left_price);

  }

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

//| 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); 

  }

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

//| Timeframe to string                                              |

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

string TimeframeToString(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 ---