How to draw MA of OBV indicator?

 

Hi everyone,

I'm a newbie who recently started learning MQL4. I've been struggling with the problem below for quite a while now without success.

Basically what I'd like to achieve is having the OBV indicator with a moving average in a separate indicator window. I used the OBV.mq4 for a start and gradually started building the code up: 

  1. I added the SetIndexBuffer and SetIndexStyle functions in init() for the second buffer which will hold my MA values
  2. I created a custom GetOBVMovingAverage() function which should look back MA_period = 200 units in the past, take the OBV values of those moments, place them all into an OBV_vals array, and then use the iMAOnArray() function to get the SMA, EMA, SMMA, or LWMA.
  3. I placed the moving average value returned by the GetOBVMovingAverage() into the MABuffer in the hope that it will show up on the indicator window.

The OBV appears properly on the chart but the MA does not. Instead, I only get a constant 0 line for the moving average. The code doesn't have any warnings or errors.  

If someone could help out an enthusiastic newbie, I'd be extremely grateful! :)

P.S: I am aware that I can add moving average to an OBV indicator on MetaTrader. However, the OBV with MA will be part of a future EA that I am planning to program and hence I need the indicator with an OBV and an MA buffers to pass on to the rest of the EA later on.

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_color2 Red

extern int ExtOBVAppliedPrice = 5;
extern int MA_period          = 200;
extern int MA_method          = 1;
extern int appliedPrice       = 5;

double OBVBuffer[];
double MABuffer[];

int init()
  {
   string sShortName;
   SetIndexBuffer(0,OBVBuffer);
   SetIndexStyle(0,DRAW_LINE);
   IndicatorDigits(0);     
   sShortName="OBV";
   IndicatorShortName(sShortName);
   SetIndexLabel(0,sShortName);

   SetIndexBuffer(1,MABuffer);
   SetIndexStyle(1,DRAW_LINE,STYLE_DOT,1);
   return(0);
  }

int start()
  {
   int    i,nLimit,nCountedBars;
   nCountedBars=IndicatorCounted();
   if(nCountedBars>0) nCountedBars--;
   nLimit=Bars-nCountedBars-1;
 
   for(i=nLimit; i>=0; i--)
     {
      // On Balance Volume Buffer
      if(i==Bars-1)
         OBVBuffer[i]=Volume[i];
      else
        {
         double dCurrentPrice=GetAppliedPrice(ExtOBVAppliedPrice, i);
         double dPreviousPrice=GetAppliedPrice(ExtOBVAppliedPrice, i+1);
         if(dCurrentPrice==dPreviousPrice)
            OBVBuffer[i]=OBVBuffer[i+1];
         else
           {
            if(dCurrentPrice<dPreviousPrice)
               OBVBuffer[i]=OBVBuffer[i+1]-Volume[i];  
            else
               OBVBuffer[i]=OBVBuffer[i+1]+Volume[i]; 
           }
         }
      
      
      // Moving Average buffer
      MABuffer[i] = GetOBVMovingAverage(MA_period, MA_method, ExtOBVAppliedPrice, i);   

     }

   return(0);
  }

double GetAppliedPrice(int nAppliedPrice, int nIndex)
  {
   double dPrice;
//----
   switch(nAppliedPrice)
     {
      case 0:  dPrice=Close[nIndex];                                  break;
      case 1:  dPrice=Open[nIndex];                                   break;
      case 2:  dPrice=High[nIndex];                                   break;
      case 3:  dPrice=Low[nIndex];                                    break;
      case 4:  dPrice=(High[nIndex]+Low[nIndex])/2.0;                 break;
      case 5:  dPrice=(High[nIndex]+Low[nIndex]+Close[nIndex])/3.0;   break;
      case 6:  dPrice=(High[nIndex]+Low[nIndex]+2*Close[nIndex])/4.0; break;
      default: dPrice=0.0;
     }

   return(dPrice);
  }

double GetOBVMovingAverage(int nPeriod, int nMethod, int nAppliedPrice, int nIndex) 
  {
   double dMA;
   double dOBV_vals[];
   int j;

   for(j=nIndex+nPeriod; j<=nIndex+1; j--) {
      dOBV_vals[j-nIndex-1] = iOBV(NULL, 0, nAppliedPrice, j);
   }
      
   dMA = iMAOnArray(dOBV_vals, 0, nPeriod, 0, nMethod, 0);
   return(dMA);
  }
 
 // Moving Average buffer
 if (i < Bars - MA_period)
    MABuffer[i] = GetOBVMovingAverage(MA_period, OBVBuffer, i);
    //MABuffer[i] = GetOBVMovingAverage(MA_period, MA_method, ExtOBVAppliedPrice, i);
//double GetOBVMovingAverage(int nPeriod, int nMethod, int nAppliedPrice, int nIndex)
double GetOBVMovingAverage(int nPeriod, double& array[], int nIndex)
{
   double dMA;
//double dOBV_vals[];
   double dOBV_vals = 0.0;
   int j;

   /*for(j=nIndex+nPeriod; j<=nIndex+1; j--) {
      dOBV_vals[j-nIndex-1] = iOBV(NULL, 0, nAppliedPrice, j);
   }*/
   for (j = nIndex; j < nIndex + nPeriod; j++)
   {
      dOBV_vals += array[j];
   }

//dMA = iMAOnArray(dOBV_vals, 0, nPeriod, 0, nMethod, 0);
   dMA = dOBV_vals / nPeriod;
   return(dMA);
}
Reason: