MTF_MCP_MA_Difference

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 indicator
11 Views
0 Downloads
0 Favorites
MTF_MCP_MA_Difference
ÿþ//+------------------------------------------------------------------+

//|                                        MTF_MCP_MA_Difference.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 timeframe multi currency pair MA Difference oscillator"

#property indicator_separate_window

#property indicator_buffers 9

#property indicator_plots   2

//--- plot Diff

#property indicator_label1  "MA Difference"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrGreen

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot Signal

#property indicator_label2  "Signal"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrRed

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- enums

enum ENUM_MA_MODE

  {

   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 string               InpSymbol1           =  "USDJPY";         // First MA symbol

input ENUM_TIMEFRAMES      InpTimeframe1        =  PERIOD_H1;        // First MA timeframe

input uint                 InpPeriodMA1         =  50;               // First MA period

input ENUM_MA_MODE         InpMethodMA1         =  METHOD_EMA;       // First MA method

input ENUM_APPLIED_PRICE   InpAppliedPrice1     =  PRICE_CLOSE;      // First MA applied price

input string               InpSymbol2           =  "EURUSD";         // Second MA symbol

input ENUM_TIMEFRAMES      InpTimeframe2        =  PERIOD_H4;        // Second MA timeframe

input uint                 InpPeriodMA2         =  50;               // Second MA period

input ENUM_MA_MODE         InpMethodMA2         =  METHOD_EMA;       // Second MA method

input ENUM_APPLIED_PRICE   InpAppliedPrice2     =  PRICE_CLOSE;      // Second MA applied price

input uint                 InpPeriodSignal      =  20;               // Signal period

input ENUM_MA_METHOD       InpMethodSignal      =  MODE_EMA;         // Signal method

input ENUM_DRAW_MODE       InpDrawMode          =  DRAW_MODE_SLOPE;  // Drawing mode

input ENUM_INPUT_YES_NO    InpPointsNormalize   =  INPUT_YES;        // Normalize points

//--- indicator buffers

double            BufferDiff[];

double            BufferSignal[];

double            BufferMA1[];

double            BufferMA2[];

double            BufferDifftmp[];

double            BufferPrice1[];

double            BufferPrice2[];

double            BufferVol1[];

double            BufferVol2[];

//--- global variables

ENUM_TIMEFRAMES   timeframe1;

ENUM_TIMEFRAMES   timeframe2;

int               period_ma1;

int               period_ma2;

int               period_sig;

int               period_max;

int               handle_ma1;

int               handle_ma2;

int               digits_1;

int               digits_2;

int               weight_sum;

//--- includes

#include <MovingAverages.mqh>

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- timer

   EventSetTimer(90);

//--- set global variables

   period_ma1=int(InpPeriodMA1<2 ? 2 : InpPeriodMA1);

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

   timeframe2=(InpTimeframe2>Period() ? InpTimeframe2 : Period());

   period_ma2=int

     (

      InpMethodMA2==InpMethodMA1 && InpAppliedPrice1==InpAppliedPrice2 && timeframe1==timeframe2 && InpPeriodMA2==period_ma1 ? period_ma1+1 :  

      InpPeriodMA2<2 ? 2 : InpPeriodMA2)

     ;

   period_sig=int(InpPeriodSignal<1 ? 1 : InpPeriodSignal);

   period_max=fmax(period_ma1,fmax(period_ma2,period_sig));

   digits_1=(int)SymbolInfoInteger(InpSymbol1,SYMBOL_DIGITS);

   digits_2=(int)SymbolInfoInteger(InpSymbol2,SYMBOL_DIGITS);

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferDiff,INDICATOR_DATA);

   SetIndexBuffer(1,BufferSignal,INDICATOR_DATA);

   SetIndexBuffer(2,BufferMA1,INDICATOR_CALCULATIONS);

   SetIndexBuffer(3,BufferMA2,INDICATOR_CALCULATIONS);

   SetIndexBuffer(4,BufferDifftmp,INDICATOR_CALCULATIONS);

   SetIndexBuffer(5,BufferPrice1,INDICATOR_CALCULATIONS);

   SetIndexBuffer(6,BufferPrice2,INDICATOR_CALCULATIONS);

   SetIndexBuffer(7,BufferVol1,INDICATOR_CALCULATIONS);

   SetIndexBuffer(8,BufferVol2,INDICATOR_CALCULATIONS);

//--- setting indicator parameters

   string label=TimeframeToString(InpTimeframe1)+" "+MethodToString(InpMethodMA1)+"("+InpSymbol1+","+PriceToString(InpAppliedPrice1)+","+(string)period_ma1+")-"+TimeframeToString(InpTimeframe2)+" "+MethodToString(InpMethodMA2)+"("+InpSymbol2+","+PriceToString(InpAppliedPrice2)+","+(string)period_ma2+"),"+(string)period_sig;

   IndicatorSetString(INDICATOR_SHORTNAME,label);

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferDiff,true);

   ArraySetAsSeries(BufferSignal,true);

   ArraySetAsSeries(BufferMA1,true);

   ArraySetAsSeries(BufferMA2,true);

   ArraySetAsSeries(BufferDifftmp,true);

   ArraySetAsSeries(BufferPrice1,true);

   ArraySetAsSeries(BufferPrice2,true);

   ArraySetAsSeries(BufferVol1,true);

   ArraySetAsSeries(BufferVol2,true);

//--- create handles

   ResetLastError();

   handle_ma1=iMA(InpSymbol1,timeframe1,1,0,MODE_SMA,InpAppliedPrice1);

   if(handle_ma1==INVALID_HANDLE)

     {

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

      return INIT_FAILED;

     }

   handle_ma2=iMA(InpSymbol2,timeframe2,1,0,MODE_SMA,InpAppliedPrice2);

   if(handle_ma2==INVALID_HANDLE)

     {

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

      return INIT_FAILED;

     }

//--- get timeframe

   Time(NULL,timeframe1,1);

   Time(NULL,timeframe2,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<fmax(period_max,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(BufferDiff,0);

      ArrayInitialize(BufferSignal,0);

      ArrayInitialize(BufferMA1,0);

      ArrayInitialize(BufferMA2,0);

      ArrayInitialize(BufferDifftmp,0);

      ArrayInitialize(BufferPrice1,0);

      ArrayInitialize(BufferPrice2,0);

     }

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

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

      return 0;

   

   int bars1=(InpSymbol1==Symbol() ? timeframe1==Period() ? rates_total : Bars(NULL,timeframe1) : Bars(InpSymbol1,timeframe1));

   int bars2=(InpSymbol2==Symbol() ? timeframe2==Period() ? rates_total : Bars(NULL,timeframe2) : Bars(InpSymbol2,timeframe2));

   

   int count1=(limit>1 ? fmin(bars1,rates_total) : 1);

   int copied1=CopyBuffer(handle_ma1,0,0,count1,BufferPrice1);

   if(copied1!=count1) return 0;

   

   int count2=(limit>1 ? fmin(bars2,rates_total) : 1);

   int copied2=CopyBuffer(handle_ma2,0,0,count2,BufferPrice2);

   if(copied2!=count2) return 0;

   

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

     {

      BufferVol1[i]=(double)Volume(InpSymbol1,timeframe1,i);

      BufferVol2[i]=(double)Volume(InpSymbol2,timeframe2,i);

   //---  0AGQB MA 1

      switch(InpMethodMA1)

        {

         case METHOD_EMA            : BufferMA1[i] = EMA(rates_total,BufferPrice1[i],BufferMA1[i+1],period_ma1,i);      break;

         case METHOD_SMMA           : BufferMA1[i] = SMMA(rates_total,BufferPrice1,BufferMA1[i+1],period_ma1,i);        break;

         case METHOD_LWMA           : BufferMA1[i] = LWMA(rates_total,BufferPrice1,period_ma1,i);                       break;

         case METHOD_WILDER_EMA     : BufferMA1[i] = Wilder(rates_total,BufferPrice1[i],BufferMA1[i+1],period_ma1,i);   break;

         case METHOD_SINE_WMA       : BufferMA1[i] = SineWMA(rates_total,BufferPrice1,period_ma1,i);                    break;

         case METHOD_TRI_MA         : BufferMA1[i] = TriMA(rates_total,BufferPrice1,period_ma1,i);                      break;

         case METHOD_LSMA           : BufferMA1[i] = LSMA(rates_total,BufferPrice1,period_ma1,i);                       break;

         case METHOD_HMA            : BufferMA1[i] = HMA(rates_total,BufferPrice1,period_ma1,i);                        break;

         case METHOD_ZL_EMA         : BufferMA1[i] = ZeroLagEMA(rates_total,BufferPrice1,BufferMA1[i+1],period_ma1,i);  break;

         case METHOD_ITREND_MA      : BufferMA1[i] = ITrend(rates_total,BufferPrice1,BufferMA1,period_ma1,i);           break;

         case METHOD_MOVING_MEDIAN  : BufferMA1[i] = Median(rates_total,BufferPrice1,period_ma1,i);                     break;

         case METHOD_GEO_MEAN       : BufferMA1[i] = GeoMean(rates_total,BufferPrice1,period_ma1,i);                    break;

         case METHOD_REMA           : BufferMA1[i] = REMA(rates_total,BufferPrice1[i],BufferMA1,period_ma1,0.5,i);      break;

         case METHOD_ILRS           : BufferMA1[i] = ILRS(rates_total,BufferPrice1,period_ma1,i);                       break;

         case METHOD_IE_2           : BufferMA1[i] = IE2(rates_total,BufferPrice1,period_ma1,i);                        break;

         case METHOD_TRI_MA_GEN     : BufferMA1[i] = TriMA_gen(rates_total,BufferPrice1,period_ma1,i);                  break;

         case METHOD_VWMA           : BufferMA1[i] = VWMA(rates_total,BufferPrice1,BufferVol1,period_ma1,i);            break;

         default /*METHOD_SMA*/     : BufferMA1[i] = SMA(rates_total,BufferPrice1,period_ma1,i);                        break;

        }

   //---  0AGQB MA 2

      switch(InpMethodMA2)

        {

         case METHOD_EMA            : BufferMA2[i] = EMA(rates_total,BufferPrice2[i],BufferMA2[i+1],period_ma2,i);      break;

         case METHOD_SMMA           : BufferMA2[i] = SMMA(rates_total,BufferPrice2,BufferMA2[i+1],period_ma2,i);        break;

         case METHOD_LWMA           : BufferMA2[i] = LWMA(rates_total,BufferPrice2,period_ma2,i);                       break;

         case METHOD_WILDER_EMA     : BufferMA2[i] = Wilder(rates_total,BufferPrice2[i],BufferMA2[i+1],period_ma2,i);   break;

         case METHOD_SINE_WMA       : BufferMA2[i] = SineWMA(rates_total,BufferPrice2,period_ma2,i);                    break;

         case METHOD_TRI_MA         : BufferMA2[i] = TriMA(rates_total,BufferPrice2,period_ma2,i);                      break;

         case METHOD_LSMA           : BufferMA2[i] = LSMA(rates_total,BufferPrice2,period_ma2,i);                       break;

         case METHOD_HMA            : BufferMA2[i] = HMA(rates_total,BufferPrice2,period_ma2,i);                        break;

         case METHOD_ZL_EMA         : BufferMA2[i] = ZeroLagEMA(rates_total,BufferPrice2,BufferMA2[i+1],period_ma2,i);  break;

         case METHOD_ITREND_MA      : BufferMA2[i] = ITrend(rates_total,BufferPrice2,BufferMA2,period_ma2,i);           break;

         case METHOD_MOVING_MEDIAN  : BufferMA2[i] = Median(rates_total,BufferPrice2,period_ma2,i);                     break;

         case METHOD_GEO_MEAN       : BufferMA2[i] = GeoMean(rates_total,BufferPrice2,period_ma2,i);                    break;

         case METHOD_REMA           : BufferMA2[i] = REMA(rates_total,BufferPrice2[i],BufferMA2,period_ma2,0.5,i);      break;

         case METHOD_ILRS           : BufferMA2[i] = ILRS(rates_total,BufferPrice2,period_ma2,i);                       break;

         case METHOD_IE_2           : BufferMA2[i] = IE2(rates_total,BufferPrice2,period_ma2,i);                        break;

         case METHOD_TRI_MA_GEN     : BufferMA2[i] = TriMA_gen(rates_total,BufferPrice2,period_ma2,i);                  break;

         case METHOD_VWMA           : BufferMA2[i] = VWMA(rates_total,BufferPrice2,BufferVol2,period_ma2,i);            break;

         default /*METHOD_SMA*/     : BufferMA2[i] = SMA(rates_total,BufferPrice2,period_ma2,i);                        break;

        }

     }

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

      BufferDifftmp[i]=(InpPointsNormalize ? (pow(10,digits_1-1)*(BufferMA1[i]-BufferMA1[i+1]))-(pow(10,digits_2-1)*(BufferMA2[i]-BufferMA2[i+1])) : BufferMA1[i]-BufferMA2[i]);

     

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

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

      DataConversion(rates_total,NULL,timeframe1,i,BufferDifftmp,BufferDiff,InpDrawMode);

   switch(InpMethodSignal)

     {

      case MODE_EMA        : return ExponentialMAOnBuffer(rates_total,prev_calculated,period_max,period_sig,BufferDiff,BufferSignal);

      case MODE_SMMA       : return SmoothedMAOnBuffer(rates_total,prev_calculated,period_max,period_sig,BufferDiff,BufferSignal);

      case MODE_LWMA       : return LinearWeightedMAOnBuffer(rates_total,prev_calculated,period_max,period_sig,BufferDiff,BufferSignal,weight_sum);

      default /*MODE_SMA*/ : return SimpleMAOnBuffer(rates_total,prev_calculated,period_max,period_sig,BufferDiff,BufferSignal);

     }

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

   return(rates_total);

  }

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

//| Custom indicator timer function                                  |

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

void OnTimer()

  {

   Time(NULL,timeframe1,1);

   Time(NULL,timeframe2,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);

  }

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

//| 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 TriMA_gen(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 MethodToString(ENUM_MA_MODE 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