Please help why Custom Indicator and Class values differ, though used the same calculation !!! (Reposted)

 

NOTE: REPOSTED, as earlier one Deleted by mistake (and dont know how to undo that)

Dear Forum Members

I have tough time to locate why my Class Object created gives different values then Custom Indicator values, even though I have used the same calculation code in both of them.

I have attached Custom Indicator, Class Object and EA to run for easy debugging.

Any help will be highly appreciated.

Files:
 

You could at least post information about your issue, screenshot, logs, etc..

I will not download 3 files and start debugging them without even knowing what you are talking about.

 
Alain Verleyen:

You could at least post information about your issue, screenshot, logs, etc..

I will not download 3 files and start debugging them without even knowing what you are talking about.

Thanks Alain for your response and below is the screen shot. Marked with RED, the Indicator EMA(5) [iFx_VW_3EMAs.mq5] values on the left of chart and below is calculated values using Class Object [FxCiVW_MA.mqh].

I have created an EA [EATest_CiVW_MA.mq5] to return values from the Class Object.

The issue is values returned by Class are not same as values from Indicator. I am not expert but feels, is ArraySetAsSeries is causing this problem?

I have also used two separate arrays for volume and VWPrice values, instead of using two dimensional array, per your suggestion in another post. However I could not get hold of using struc instead of two dimensional array.

I have copied & pasted the Indicator + Class Code for your easy viewing reference without downloading them.

//+----------------------------------------------------------------------------------------------------------+
//| FxCiVW_MA.mqh
//| CLASS to return 'Volume Weighted Moving Average' Indicator values
//+----------------------------------------------------------------------------------------------------------+
class FxCiVW_MA
  {
private:
  //--- class variable for parameters
    string              m_Symbol;             // Symbol
    ENUM_TIMEFRAMES     m_TimeFrame;          // Timeframe
    int                 m_MAPeriod;           // Period
    //int                 m_MAShift;            // Shift
    //ENUM_MA_METHOD      m_MAMethod;           // Moving Average method
    ENUM_APPLIED_PRICE  m_MAAppliedPrice;     //
  //--- Instance of other Class(s)
    //CLog*             m_log;                // Logging

public:
  //--- Parametric Contstructor and default Destructor methods
                        FxCiVW_MA(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,int pMAPeriod);
                       ~FxCiVW_MA(void);
  //--- Specific methods of Class FxCiVW_MA
    bool                Get_iVW_EMA(int pBarStart,int pBarCount,double &VW_EMA[]);
  };
//+----------------------------------------------------------------------------------------------------------+
//| METHOD:       FxCiVW_MA()
//| APPLICATION:  'parametric constructor' method with parameters passed into the Class
//+----------------------------------------------------------------------------------------------------------+
FxCiVW_MA::FxCiVW_MA(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,int pMAPeriod)
  {
    m_Symbol         = pSymbol;
    m_TimeFrame      = pTimeFrame;
    m_MAPeriod       = pMAPeriod;
    //m_MAShift        = pMAShift;
    //m_MAAppliedPrice = pAppliedPrice;
    //m_log = CLog::GetLog();
  } // END Of FxCiVW_MA()
//+----------------------------------------------------------------------------------------------------------+
//| METHOD:       FxCiVW_MA()
//| APPLICATION:  default destructor method
//+----------------------------------------------------------------------------------------------------------+
FxCiVW_MA::~FxCiVW_MA(void)
  {
//---
  } // END Of ~FxCiVW_MA()
//+----------------------------------------------------------------------------------------------------------+
//| METHOD:       Get_iVW_EMA()
//| APPLICATION:  Calculate VW EMA values
//+----------------------------------------------------------------------------------------------------------+
bool FxCiVW_MA::Get_iVW_EMA(int pBarStart,int pBarCount,double &VW_EMA[])
  {
    double aPrice[], aVolume[];
    ArrayResize(aPrice,pBarCount+1);
    ArrayResize(aVolume,pBarCount+1);
    ArrayResize(VW_EMA,pBarCount+1);
    ArraySetAsSeries(aPrice,true);
    ArraySetAsSeries(aVolume,true);
    ArraySetAsSeries(VW_EMA,true);

    double multiplier = 2.0/(1.0 + m_MAPeriod);
  //+--------------------------------------------------------------------------------------------------------+
  //| Main Calculation Block for VW EMA Values
  //+--------------------------------------------------------------------------------------------------------+
    //for(int i=(int)MathMax(prev_calculated-1,0); i < rates_total; i++)
    for(int i=(int)MathMax(pBarStart-1,0); i < pBarCount; i++)
      {
        double vol   = (double)iVolume(m_Symbol,m_TimeFrame,i);   // tick volume by default
        double price = iClose(m_Symbol,m_TimeFrame,i);

        if(i < 2)   // avoid Zero bar, as it keeps changing and affect the Average Value
          {
            aPrice[i]  = (vol * price);
            aVolume[i] = (vol);
            continue;
          }
      //---
        aPrice[i]  = aPrice[i-1]  + multiplier * (vol * price - aPrice[i-1]);
        aVolume[i] = aVolume[i-1] + multiplier * (vol         - aVolume[i-1]);
        VW_EMA[i]  = aPrice[i] / aVolume[i];
      } // ENF Of for ... loop
  //---
    return(true);
  } // END Of Get_iVW_EMA() method
//+----------------------------------------------------------------------------------------------------------+
//+----------------------------------------------------------------------------------------------------------+
//| iFx VW_3EMAs.mq5
//+----------------------------------------------------------------------------------------------------------+
  #property description "Volume Weighted Exponential Moving Average Indicator"
  #property description "3 EMAs ... EMA Fastest, EMA Fast and EMA Slow"

  #property indicator_chart_window
  #property indicator_buffers 3
  #property indicator_plots   3
  //+--------------------------------------------------------------------------------------------------------+
  //| #property for Plotting Indicator Labels in SubWindow
  //+--------------------------------------------------------------------------------------------------------+
  //--- Properties for EMAFastest
    #property indicator_type1   DRAW_LINE
    #property indicator_color1  clrOrange
    #property indicator_style1  STYLE_SOLID
    #property indicator_width1  1
  //--- Properties for EMAFast
    #property indicator_type2   DRAW_LINE
    #property indicator_color2  clrOrange
    #property indicator_style2  STYLE_SOLID
    #property indicator_width2  2
  //--- Properties for EMASlow
    #property indicator_type3   DRAW_LINE
    #property indicator_color3  clrOrange
    #property indicator_style3  STYLE_SOLID
    #property indicator_width3  3
//+----------------------------------------------------------------------------------------------------------+
//| Define Input Parameters
//+----------------------------------------------------------------------------------------------------------+
  input int                 inpMAPeriod_Fastest = 5;        // Averaging period
  input int                 inpMAPeriod_Fast    = 8;        // Averaging period
  input int                 inpMAPeriod_Slow    = 13;       // Averaging period
  input ENUM_APPLIED_PRICE  inpAppliedPrice     = PRICE_CLOSE;
  input bool                inpVolumeReal       = false;    // if 'true' = use real volume
//+----------------------------------------------------------------------------------------------------------+
//| Define Indicator Handle(s) and Buffer(s)
//+----------------------------------------------------------------------------------------------------------+
  double EMAFastest[], EMAFast[], EMASlow[];
//+----------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function
//+----------------------------------------------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,EMAFastest,INDICATOR_DATA); 
   SetIndexBuffer(1,EMAFast,INDICATOR_DATA); 
   SetIndexBuffer(2,EMASlow,INDICATOR_DATA); 

   IndicatorSetString(INDICATOR_SHORTNAME,"iFx VW 3EMAs ("+string(inpMAPeriod_Fastest)+") ("+string(inpMAPeriod_Fast)+") ("+string(inpMAPeriod_Slow)+")");
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   PlotIndexSetString(0,PLOT_LABEL,"VW EMA ("+(string)inpMAPeriod_Fastest+")");
   PlotIndexSetString(1,PLOT_LABEL,"VW EMA ("+(string)inpMAPeriod_Fast+")");
   PlotIndexSetString(2,PLOT_LABEL,"VW EMA ("+(string)inpMAPeriod_Slow+")");
   return(0);
}
  //+--------------------------------------------------------------------------------------------------------+
  //| define local variables
  //+--------------------------------------------------------------------------------------------------------+
    double aPriceFastest[], aVolumeFastest[];
    double aPriceFast[],    aVolumeFast[];
    double aPriceSlow[],    aVolumeSlow[];
//+----------------------------------------------------------------------------------------------------------+
//| 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[])
  {
    double alphaMAFastest = 2.0/(1.0 + inpMAPeriod_Fastest);
    double alphaMAFast    = 2.0/(1.0 + inpMAPeriod_Fast);
    double alphaMASlow    = 2.0/(1.0 + inpMAPeriod_Slow);

    ArrayResize(aPriceFastest,rates_total);
    ArrayResize(aVolumeFastest,rates_total);
    ArrayResize(EMAFastest,rates_total);

    ArrayResize(aPriceFast,rates_total);
    ArrayResize(aVolumeFast,rates_total);
    ArrayResize(EMAFast,rates_total);

    ArrayResize(aPriceSlow,rates_total);
    ArrayResize(aVolumeSlow,rates_total);
    ArrayResize(EMASlow,rates_total);
  //+--------------------------------------------------------------------------------------------------------+
  //| Main Calculation Block for VW EMA Values
  //+--------------------------------------------------------------------------------------------------------+
    for(int i=(int)MathMax(prev_calculated-1,0); i < rates_total; i++)
      {
        double vol;
        double price = getPrice(inpAppliedPrice,open,close,high,low,i,rates_total);

        if(inpVolumeReal)
          vol = (double)volume[i];
        else
          vol = (double)tick_volume[i];          
  
        if(i < 2)   // avoid Zero bar, as it keeps changing and affect the Average Value
          {
            aPriceFastest[i]  = (vol * price);
            aVolumeFastest[i] = (vol);

            aPriceFast[i]     = (vol * price);
            aVolumeFast[i]    = (vol);

            aPriceSlow[i]     = (vol * price);
            aVolumeSlow[i]    = (vol);

            continue;
          }

        aPriceFastest[i]  = aPriceFastest[i-1]  + alphaMAFastest * (vol * price - aPriceFastest[i-1]);
        aVolumeFastest[i] = aVolumeFastest[i-1] + alphaMAFastest * (vol         - aVolumeFastest[i-1]);
        EMAFastest[i] = aPriceFastest[i] / aVolumeFastest[i];

        aPriceFast[i]  = aPriceFast[i-1]  + alphaMAFast * (vol * price - aPriceFast[i-1]);
        aVolumeFast[i] = aVolumeFast[i-1] + alphaMAFast * (vol         - aVolumeFast[i-1]);
        EMAFast[i] = aPriceFast[i] / aVolumeFast[i];

        aPriceSlow[i]  = aPriceSlow[i-1]  + alphaMASlow * (vol * price - aPriceSlow[i-1]);
        aVolumeSlow[i] = aVolumeSlow[i-1] + alphaMASlow * (vol         - aVolumeSlow[i-1]);
        EMASlow[i] = aPriceSlow[i] / aVolumeSlow[i];
      } // ENF Of for ... loop
  //---
    return(rates_total);
  }
//+----------------------------------------------------------------------------------------------------------+

//+----------------------------------------------------------------------------------------------------------+
//| Function getPrice()                                                                  
//+----------------------------------------------------------------------------------------------------------+

double workHa[][4];
double getPrice(ENUM_APPLIED_PRICE price, const double& open[], const double& close[], const double& high[],
                const double& low[], int i, int bars)
{
   switch (price)
   {
      case PRICE_CLOSE:     return(close[i]);
      case PRICE_OPEN:      return(open[i]);
      case PRICE_HIGH:      return(high[i]);
      case PRICE_LOW:       return(low[i]);
      case PRICE_MEDIAN:    return((high[i]+low[i])/2.0);
      case PRICE_TYPICAL:   return((high[i]+low[i]+close[i])/3.0);
      case PRICE_WEIGHTED:  return((high[i]+low[i]+close[i]+close[i])/4.0);
      //case pr_average:   return((high[i]+low[i]+close[i]+open[i])/4.0);
   }
   return(0);
}

Indicator and Calculated Values in ClassObject