//+------------------------------------------------------------------+
//|                                              AIS Double LWMA.mq4 |
//|                                                        AIS Forex |
//|                        https://www.mql5.com/ru/users/aleksej1966 |
//+------------------------------------------------------------------+
#property copyright "AIS Forex"
#property link      "https://www.mql5.com/ru/users/aleksej1966"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_type1  DRAW_LINE
#property indicator_label1 "Double LWMA"
#property indicator_color1 clrBlue
#property indicator_width1 1
#property indicator_style1 STYLE_SOLID

input ENUM_APPLIED_PRICE iPrice=PRICE_CLOSE;
input ushort iPeriod=10;

int period,weight[],denom=0;
double buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,buffer,INDICATOR_DATA);
   ArraySetAsSeries(buffer,true);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);

   period=MathMax(3,iPeriod);
   int array[],minus=(period+1)/2;
   ArrayResize(array,period);
   for(int i=0; i<period; i++)
     {
      array[i]=period-i-1;
      if(i>=minus)
         array[i]=-array[i];
     }

   ArrayResize(weight,2*period-1);
   ArrayInitialize(weight,0);
   for(int i=0; i<period; i++)
      for(int j=0; j<period; j++)
         weight[i+j]=weight[i+j]+array[i]*array[j];

   period=2*period-1;
   for(int i=0; i<period; i++)
      denom=denom+weight[i];
//---
   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[])
  {
//---
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);

   int bars=prev_calculated>0? rates_total-prev_calculated:rates_total-period-1;

   for(int i=bars; i>=0; i--)
     {
      double sum=0;
      for(int j=0; j<period; j++)
        {
         int p=i+j;
         sum=sum+weight[j]*price(open[p],high[p],low[p],close[p]);
        }

      buffer[i]=sum/denom;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double price(double o,double h,double l,double c)
  {
   if(iPrice==PRICE_CLOSE)
      return(c);
   if(iPrice==PRICE_OPEN)
      return(o);
   if(iPrice==PRICE_HIGH)
      return(h);
   if(iPrice==PRICE_LOW)
      return(l);
   if(iPrice==PRICE_MEDIAN)
      return((h+l)/2);
   if(iPrice==PRICE_TYPICAL)
      return(h+l+c)/3;
   return(h+l+2*c)/4;
  }
//+------------------------------------------------------------------+
