AD Smoothing

 
Hello everybody,

i have this AD indicator and want to apply two moving averages. The first moving average should use the price data from the AD. The second moving average should use the smoothed price data from the first moving average.

It´s easy to implement one moving average which uses the buffer from the AD, but the second indicator uses also the buffer from the AD, although i have used the buffer from the first moving average...
This is the code from the AD.mq5

//+------------------------------------------------------------------+
//|                                                           AD.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Accumulation/Distribution"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
#property indicator_label1  "A/D"
//---Smoothed
#property indicator_label2  "Smoothed"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---Smoothed 2
#property indicator_label2  "Smoothed2"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGreen
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
#include <MovingAverages.mqh>

//--- input params
input int Smoothed_Period = 18;
input ENUM_MA_METHOD Smoothed_Mode = MODE_EMA;
input int Double_Smoothed_Period = 18;
input ENUM_MA_METHOD Double_Smoothed_Mode = MODE_EMA;
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volume type
//---- buffers
double ExtADbuffer[];
double SmoothedBuffer[];
double DoubleSmoothedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//--- indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME,"A/D");
//---- index buffer
   SetIndexBuffer(0,ExtADbuffer);
//--- set index draw begin
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1);
// set index smoothed buffer 
   SetIndexBuffer(1, SmoothedBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, DoubleSmoothedBuffer, INDICATOR_DATA);


//---- OnInit done
   
  }
//+------------------------------------------------------------------+
//| Accumulation/Distribution                                        |
//+------------------------------------------------------------------+
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 &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
//--- check for bars count
   if(rates_total<2)
      return(0); //exit with zero result
//--- get current position
   int pos=prev_calculated-1;
   if(pos<0) pos=0;
//--- calculate with appropriate volumes
   if(InpVolumeType==VOLUME_TICK)
      Calculate(rates_total,pos,High,Low,Close,TickVolume);
   else
      Calculate(rates_total,pos,High,Low,Close,Volume);
//----
   
  
  
  switch(Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    }
    
     switch(Double_Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    }
  return(rates_total);
  }
//+------------------------------------------------------------------+
//| Calculating with selected volume                                 |
//+------------------------------------------------------------------+
void Calculate(const int rates_total,const int pos,
               const double &High[],
               const double &Low[],
               const double &Close[],
               const long &Volume[])
  {
   double hi,lo,cl;
//--- main cycle
   for(int i=pos;i<rates_total && !IsStopped();i++)
     {
      //--- get some data from arrays
      hi=High[i];
      lo=Low[i];
      cl=Close[i];
      //--- calculate new AD
      double sum=(cl-lo)-(hi-cl);
      if(hi==lo) sum=0.0;
      else       sum=(sum/(hi-lo))*Volume[i];
      if(i>0) sum+=ExtADbuffer[i-1];
      ExtADbuffer[i]=sum;
     }


  }
//+------------------------------------------------------------------+
There is some little part missing and i don´t know what it is. I would appreciate your help. And i know i am asking quite a lot since i have startet with mql5 but i do my best to answer the questions from others too.
Entdecken Sie neue Möglichkeiten des MetaTrader 5 mit MQL5 Gemeinschaft und Services
Entdecken Sie neue Möglichkeiten des MetaTrader 5 mit MQL5 Gemeinschaft und Services
  • 2021.04.12
  • www.mql5.com
MQL5: eine Sprache von Handelsstrategien, eingebaut in die Handelsplattform MetaTrader 5, mit der man eigene Handelsroboter, technische Indikatoren, Skripte und Funktionsbibliotheken
 
You are missing double_smoothed_period.

MODE_EMA is probably the second entry in the enum definition. Therefore you ask for 1 period of xMA, thus recieving a copy of the original value.

You could check if volume is NULL and switch to tick_volume automatically.

Hope it helps.
 
Thanks for the answer. But i don´t get it.

what has the volume to do with this two smoothing MA´s.

It changes nothing, when i am going to calculate the indicator with tick volume...
 
//---Smoothed 2
#property indicator_label3  "Smoothed2"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGreen
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
 
steyr6155:
Thanks for the answer. But i don´t get it.

what has the volume to do with this two smoothing MA´s.

It changes nothing, when i am going to calculate the indicator with tick volume...


here is your issue

     switch(Double_Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Mode, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    }



Concerning the volume, that was just an idea to make it automatically...

 
omg. so obvious...

It must be Double_Smoothed_Period instead of Double_Smoothed_Mode

Thank you both!

If anyone needs it. Here is the correct file:

//+------------------------------------------------------------------+
//|                                                           AD.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Accumulation/Distribution"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
#property indicator_label1  "A/D"
//---Smoothed
#property indicator_label2  "Smoothed"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//---Smoothed 2
#property indicator_label3  "Smoothed2"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGreen
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
#include <MovingAverages.mqh>

//--- input params
input int Smoothed_Period = 18;
input ENUM_MA_METHOD Smoothed_Mode = MODE_EMA;
input int Double_Smoothed_Period = 30;
input ENUM_MA_METHOD Double_Smoothed_Mode = MODE_SMA;
input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volume type
//---- buffers
double ExtADbuffer[];
double SmoothedBuffer[];
double DoubleSmoothedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator digits
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//--- indicator short name
   IndicatorSetString(INDICATOR_SHORTNAME,"A/D");
//---- index buffer
   SetIndexBuffer(0,ExtADbuffer);
//--- set index draw begin
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1);
// set index smoothed buffer 
   SetIndexBuffer(1, SmoothedBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, DoubleSmoothedBuffer, INDICATOR_DATA);


//---- OnInit done
   
  }
//+------------------------------------------------------------------+
//| Accumulation/Distribution                                        |
//+------------------------------------------------------------------+
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 &TickVolume[],
                const long &Volume[],
                const int &Spread[])
  {
//--- check for bars count
   if(rates_total<2)
      return(0); //exit with zero result
//--- get current position
   int pos=prev_calculated-1;
   if(pos<0) pos=0;
//--- calculate with appropriate volumes
   
      Calculate(rates_total,pos,High,Low,Close,TickVolume);

   
  
  
  switch(Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtADbuffer, SmoothedBuffer);
      break;
    }
    
     switch(Double_Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Period, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Double_Smoothed_Period, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Period, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Double_Smoothed_Period, SmoothedBuffer, DoubleSmoothedBuffer);
      break;
    }
  return(rates_total);
  }
//+------------------------------------------------------------------+
//| Calculating with selected volume                                 |
//+------------------------------------------------------------------+
void Calculate(const int rates_total,const int pos,
               const double &High[],
               const double &Low[],
               const double &Close[],
               const long &Volume[])
  {
   double hi,lo,cl;
//--- main cycle
   for(int i=pos;i<rates_total && !IsStopped();i++)
     {
      //--- get some data from arrays
      hi=High[i];
      lo=Low[i];
      cl=Close[i];
      //--- calculate new AD
      double sum=(cl-lo)-(hi-cl);
      if(hi==lo) sum=0.0;
      else       sum=(sum/(hi-lo))*Volume[i];
      if(i>0) sum+=ExtADbuffer[i-1];
      ExtADbuffer[i]=sum;
     }


  }
 
Haven't you had compiler warnings?

Take them serious... ;-)
 
Dominik Egert:
Haven't you had compiler warnings?

Take them serious... ;-)
haha, no there wasn´t any errors :D.

I have another indicator which i want to smooth. It´s the ROC.

I am sure it´s none of the mistakes above...


Do you have any Idea, what possibly could be wrong in this code?

//+------------------------------------------------------------------+
//|                                                          ROC.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include <MovingAverages.mqh>
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Rate of Change"
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen
//--- input parameters
input int InpRocPeriod=12; // Period
input int Smoothed_Period = 18;
input ENUM_MA_METHOD Smoothed_Mode = MODE_EMA;
//---Smoothed
#property indicator_label2  "Smoothed"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1


//--- indicator buffers
double    ExtRocBuffer[];
double SmoothedBuffer[];

//--- global variable
int       ExtRocPeriod;
//+------------------------------------------------------------------+
//| Rate of Change initialization function                           |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(InpRocPeriod<1)
     {
      ExtRocPeriod=12;
      Print("Incorrect value for input variable InpRocPeriod =",InpRocPeriod,
            "Indicator will use value =",ExtRocPeriod,"for calculations.");
     }
   else ExtRocPeriod=InpRocPeriod;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtRocBuffer,INDICATOR_DATA);   
  

//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"ROC("+string(ExtRocPeriod)+")");
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtRocPeriod);
   
   SetIndexBuffer(1, SmoothedBuffer, INDICATOR_DATA);

//--- initialization done
  }
//+------------------------------------------------------------------+
//| Rate of Change                                                   |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[])
  {
//--- check for rates count
   if(rates_total<ExtRocPeriod)
      return(0);
//--- preliminary calculations
   int pos=prev_calculated-1; // set calc position
   if(pos<ExtRocPeriod)
      pos=ExtRocPeriod;
//--- the main loop of calculations
   for(int i=pos;i<rates_total && !IsStopped();i++)
     {
      if(price[i]==0.0)
         ExtRocBuffer[i]=0.0;
      else
         ExtRocBuffer[i]=(price[i]-price[i-ExtRocPeriod])/price[i]*100;
     }
//--- OnCalculate done. Return new prev_calculated.

  switch(Smoothed_Mode)
    {
    case MODE_EMA:
      ExponentialMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtRocBuffer, SmoothedBuffer);
      break;
    case MODE_LWMA:
      LinearWeightedMAOnBuffer(rates_total, prev_calculated,  0, Smoothed_Period, ExtRocBuffer, SmoothedBuffer);
      break;
    case MODE_SMA:
      SimpleMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtRocBuffer, SmoothedBuffer);
      break;
    case MODE_SMMA:
      SmoothedMAOnBuffer(rates_total, prev_calculated, 0, Smoothed_Period, ExtRocBuffer, SmoothedBuffer);
      break;
    }

   return(rates_total);
  }
//+------------------------------------------------------------------+
PS.: the compiler says: 0 errors, 0 warnings ;D good to go!
 
steyr6155:
haha, no there wasn´t any errors :D.

I have another indicator which i want to smooth. It´s the ROC.

I am sure it´s none of the mistakes above...


Do you have any Idea, what possibly could be wrong in this code?

The argument of "LinearWeightedMAOnBuffer" is as follows on my "MovingAverages.mqh".

int LinearWeightedMAOnBuffer(const int rates_total,const int prev_calculated,const int begin,
                             const int period,const double& price[],double& buffer[],int &weightsum)

In your program, the variable corresponding to "weightsum" is missing, so I also get an error.

Your mqh file may be different from ours.

 
you are right, my function is different "&weightsum" is missing. It´s a little strange, because it seems to work but i never had changed something. I just restarted the mt5...

int LinearWeightedMAOnBuffer(const int rates_total,const int prev_calculated,const int begin,const int period,const double& price[],double& buffer[])
  {
//--- check period
   if(period<=1 || period>(rates_total-begin))
      return(0);
//--- save as_series flags
   bool as_series_price=ArrayGetAsSeries(price);
   bool as_series_buffer=ArrayGetAsSeries(buffer);

   ArraySetAsSeries(price,false);
   ArraySetAsSeries(buffer,false);
//--- calculate start position
   int i,start_position;

   if(prev_calculated<=period+begin+2)  // first calculation or number of bars was changed
     {
      //--- set empty value for first bars
      start_position=period+begin;

      for(i=0; i<start_position; i++)
         buffer[i]=0.0;
     }
   else
      start_position=prev_calculated-2;
//--- calculate first visible value
   double sum=0.0,lsum=0.0;
   int    l,weight=0;

   for(i=start_position-period,l=1; i<start_position; i++,l++)
     {
      sum   +=price[i]*l;
      lsum  +=price[i];
      weight+=l;
     }
   buffer[start_position-1]=sum/weight;
//--- main loop
   for(i=start_position; i<rates_total; i++)
     {
      sum      =sum-lsum+price[i]*period;
      lsum     =lsum-price[i-period]+price[i];
      buffer[i]=sum/weight;
     }
Reason: