Help working with buffers

 

Hi experts. I am new with MT4 and am trying to pick it up with all the great resources freely available. I tried my hand at putting together a custom indicator but just didn't work. No errors upon attaching to chart but no signal was drawn.

The effect I am trying to achieve is to multiply EMA(Vol) with EMA(Price). Yes, I am aware that the volume is tick volume and not transaction volume. And yes, I know what iMA() does give EMA(price) but I coded it the same way as for volume, just for the heck of it. (if this is totally wrong, pls let me know too)

Would seriously appreciate assistance to point out what went wrong with the code. Thanks much!

Code as below :

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue

//---- input parameters
extern int MA_Period=13;
extern int MA_Shift=0;
extern int MA_Method=0;

//---- buffers
double VPABuffer[];
double VolEMABuffer[];  
double PriceEMABuffer[];  

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
   SetIndexBuffer(0,VPABuffer);
      
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);

//---- name for DataWindow and indicator subwindow label
   sShortName="VPA("+MA_Period+")";
   IndicatorShortName(sShortName);
   SetIndexLabel(0,sShortName);


//----
   return(0);
  }


//+------------------------------------------------------------------+
//| VPA Index indicator                                              |
//+------------------------------------------------------------------+
int start()
  {
   int nLimit;
   int nCountedBars=IndicatorCounted();



//---- insufficient data
   if(Bars<=MA_Period) return(0);
//---- last counted bar will be recounted
   if(nCountedBars>MA_Period) nCountedBars--;
   nLimit=Bars-nCountedBars;

   double ewmaMultiplier=2.0/(MA_Period+1);
   int    pos=Bars-2;

   if(nCountedBars>2) pos=Bars-nCountedBars-1;

   while(pos>=0)
     {

      if(pos==Bars-2) 
         {
            VolEMABuffer[pos+1]=Volume[pos+1];
            PriceEMABuffer[pos+1]=Close[pos+1];
          }
          
      VolEMABuffer[pos]=Volume[pos]*ewmaMultiplier+VolEMABuffer[pos+1]*(1-ewmaMultiplier);
      PriceEMABuffer[pos]=Close[pos]*ewmaMultiplier+PriceEMABuffer[pos+1]*(1-ewmaMultiplier);
 
      VPABuffer[pos]=VolEMABuffer[pos]*PriceEMABuffer[pos];

           pos--;
     }
 
//---- done
   return(0);
  }
//+------------------------------------------------------------------+

 
wolvl:
The effect I am trying to achieve is to multiply EMA(Vol) with EMA(Price).
Would seriously appreciate assistance to point out what went wrong with the code. Thanks much!
  1. Contradictory information on IndicatorCounted() - MQL4 forum the nCountedBars-- is unnecessary. Your look back is one
    //---- last counted bar will be recounted
       if(nCountedBars>MA_Period) nCountedBars--;
       nLimit=Bars-nCountedBars;
    
       double ewmaMultiplier=2.0/(MA_Period+1);
       int    pos=Bars-2;
    
       if(nCountedBars>2) pos=Bars-nCountedBars-1;
    
       while(pos>=0)
         {
    
          if(pos==Bars-2) 
             {
                VolEMABuffer[pos+1]=Volume[pos+1];
                PriceEMABuffer[pos+1]=Close[pos+1];
              }
          :
          pos--;
       }
    

    if(nCountedBars == 0){
       VolEMABuffer[Bars-1]  = Volume[Bars-1];
       PriceEMABuffer[Bars-1]=  Close[Bars-1];
       nCountedBars = 1; // Don't look past last bar.
    }
    double ewmaMultiplier=2.0/(MA_Period+1);
    for (pos = Bars -1 -nCountedBars; pos >=0; pos--){
       :
       //pos--;
    }

  2.   VolEMABuffer[pos]=Volume[pos]*ewmaMultiplier+VolEMABuffer[pos+1]  *(1-ewmaMultiplier);
    PriceEMABuffer[pos]= Close[pos]*ewmaMultiplier+PriceEMABuffer[pos+1]*(1-ewmaMultiplier);
    EMA's should not be coded like that as it amplifies floating point round off. The equivalent, more efficient equation that removes round off error:
      VolEMABuffer[pos]=   VolEMABuffer[pos+1] + ewmaMultiplier *(Volume[pos] - VolEMABuffer[pos+1]  );
    PriceEMABuffer[pos]= PriceEMABuffer[pos+1] + ewmaMultiplier *(Close[pos]  - PriceEMABuffer[pos+1]);

  3. The range of volume is 1-1000 and the range of price is 1.2345-1.2456 so scaled all you see is volume.
  4. You said "multiply EMA(Vol) with EMA(Price)." but in your code you are creating two separate lines not multiplying anything.
 
WHRoeder:
  1. Contradictory information on IndicatorCounted() - MQL4 forum the nCountedBars-- is unnecessary. Your look back is one


  2. EMA's should not be coded like that as it amplifies floating point round off. The equivalent, more efficient equation that removes round off error:

  3. The range of volume is 1-1000 and the range of price is 1.2345-1.2456 so scaled all you see is volume.
  4. You said "multiply EMA(Vol) with EMA(Price)." but in your code you are creating two separate lines not multiplying anything.


Thanks WHRoeder, I will re-code and test with your suggestions.

I do have a multiplication taking place just the below line creating the EMA buffers. VPABuffer is my actual indicator line.

      VPABuffer[pos]=VolEMABuffer[pos]*PriceEMABuffer[pos];
 

Have implemented WHRoeder's suggestions and it still doesn't paint the indicator correctly. Actually, to be more accurate, still no line is drawn. :(

Re-posting the complete revised version for assistance... there could be something fundamental that i have totally missed out on.

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 DodgerBlue

//---- input parameters
extern int MA_Period=13;

//---- buffers
double VPABuffer[];
double VolEMABuffer[];  
double PriceEMABuffer[];  

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string sShortName;
   SetIndexBuffer(0,VPABuffer);
      
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);

//---- name for DataWindow and indicator subwindow label
   sShortName="VPA("+MA_Period+")";
   IndicatorShortName(sShortName);
   SetIndexLabel(0,sShortName);


//----
   return(0);
  }


//+------------------------------------------------------------------+
//| VPA Index indicator                                              |
//+------------------------------------------------------------------+
int start()
  {

   int nCountedBars=IndicatorCounted();

//---- insufficient data
   if(Bars<=MA_Period) return(0);
//---- last counted bar will be recounted
   if(nCountedBars == 0) 
   {
      VolEMABuffer[Bars]=Volume[Bars];
      PriceEMABuffer[Bars]=Close[Bars];
      nCountedBars = 1; //Don't look past last bar
   }   
   
   double ewmaMultiplier =2.0/(MA_Period+1);
   
   for (int pos = Bars -1 -nCountedBars; pos>=0; pos--)
   {

      VolEMABuffer[pos]= VolEMABuffer[pos+1] + ewmaMultiplier * (Volume[pos]-VolEMABuffer[pos+1]);
      PriceEMABuffer[pos]=PriceEMABuffer[pos+1] + ewmaMultiplier * (Close[pos]- PriceEMABuffer[pos+1]);
      VPABuffer[pos]=VolEMABuffer[pos]*PriceEMABuffer[pos];

     }
 
//---- done
   return(0);
  }
//+------------------------------------------------------------------+

 

Add this on init()

   string sShortName;
   IndicatorBuffers(3);
   SetIndexBuffer(0,VPABuffer);
   SetIndexBuffer(1,VolEMABuffer);
   SetIndexBuffer(2,PriceEMABuffer);   
//---- indicator line
   SetIndexStyle(0,DRAW_LINE);

and yell "Awesome".

:D

 

AWESOME!! and yes, i did this part too :D

#property indicator_buffers 3

Thanks much onewithzachy and of course WHRoeder for code optimization!

Reason: