recursion

 

I have a function a bit like this:

double obv(int n, int j, const double &close1[], const long &tick_volume1[])
{

if (close1[j]>close1[j-n]){ExtOBVBuffer2[j]=ExtOBVBuffer2[j-n]+vol(n,j,tick_volume1);}
  
      if (close1[j]<close1[j-n]){ExtOBVBuffer2[j]=ExtOBVBuffer2[j-n]-vol(n,j,tick_volume1);}
  
            else if (close1[j]==close1[j-n]){ExtOBVBuffer2[j]=ExtOBVBuffer2[j-n];}
   }
   else {ExtOBVBuffer2[j]=ExtOBVBuffer2[j-1];}

}


And it works. However if:

a= obv(1, i, close,tick_volume) and

b= obv(2, i, close,tick_volume)

yet buffer[i]= a + b does not result in the sum of its parts and I don't know why.

Consequently I tried recursion:

double recur(int p, int k, const double &close3[], const long &tick_volume3[])
{
  
      if(p>0)
      {
      return(obv(p, k, close3,tick_volume3)+obv(p-1, k, close3,tick_volume3);
      }
      else{
      return (1);
   }
}


...and the answer does not come out as the sum of its parts either.

What I am wanting to know is, am I missing something in the laws of functions or do you reckon I've made a mistake somewhere?

thanks.

 

Could you provide results which you are getting and results which you are expecting to get or provide a full source code to reproduce?

 
return(obv(p, k, close3,tick_volume3)+obv(p-1, k, close3,tick_volume3);

may be the second call of this line must be recur fuction, not obv?

 

The loop will be better than recursion, it is exclude the stackout for large values of P

double calc(int p,int k,const double &close3[],const long &tick_volume3[])
  {
   double result=1.0;
//---
   for(;p>0;p--)
      result+=obv(p,k,close3,tick_volume3);
//--- 
   return(result);
  }
 

First, thanks for your comments. The program below is written so that you can view any OBV (above 5 mins) on a five minute graph, starting on ANY candle:

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//---- plot Label1
#property indicator_label1  "OBV "
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrWhite
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1


input int timel=0; //Time
input int candles=1; //Candles

//--- indicator buffers

double         Buffer2[];
double         Buffer3[];
double         Buffer15[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buffer15,INDICATOR_DATA);
   SetIndexBuffer(1,Buffer2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,Buffer3,INDICATOR_CALCULATIONS);

  
   ResetLastError();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
  
      //--- variables
   int    pos;
  
//--- check for bars count
   if(rates_total<2)
      return(0);
//--- starting calculation
   pos=prev_calculated-1;
//--- correct position, when it's first iteration
    
        if(pos<25000)
  
     {
      pos=25000;
     Buffer2[0]=(double)tick_volume[0];
     }

   
 for(int i=pos;i<rates_total;i++)
     {
  
Buffer15[i]= obv(timel,candles,i,close,tick_volume,time);

   }
   return(rates_total);
  }
//+------------------------------------------------------------------+

  //******************
  // Function vol
  //******************
 
double vol(int o,int k,const long &tick_volume2[])
{
   double j=0;
  
   for(int i=0;i<o;i++)
   {
  
   j += (double) tick_volume2[k-i];
  
   }
   return(j);
}

  //******************
  // Function obv
  //******************
 
double obv(int o/*time changer*/,int n/*candles*/,int j, const double &close1[],const long &tick_volume1[],const datetime &time1[])
{
      Buffer2[j]=0;
      int setting = 300*n;

if((time1[j] % setting==300*o))

{     if (close1[j]>close1[j-n]){Buffer2[j]=Buffer2[j-n]+vol(n,j,tick_volume1);}
  
      if (close1[j]<close1[j-n]){Buffer2[j]=Buffer2[j-n]-vol(n,j,tick_volume1);}
  
            else if (close1[j]==close1[j-n]){Buffer2[j]=Buffer2[j-n];}
   }
   else {Buffer2[j]=Buffer2[j-1];}

 
   return(Buffer2[j]);
}


The problem is that if:

a= obv(4,5,i,close,tick_volume,time)

b= obv(9,10,i,close,tick_volume,time)

yet a+b does not equal the sum of its parts.

for example try:

Buffer15[i]= obv(4,5,i,close,tick_volume,time);

Buffer15[i]= obv(9,10,i,close,tick_volume,time);

Buffer15[i]= obv(4,5,i,close,tick_volume,time)+obv(9,10,i,close,tick_volume,time);

I came to the conclusion that buffers in a function have global effects. Am I wrong?

 
Abraham:


I came to the conclusion that buffers in a function have global effects. Am I wrong?


Of course. Buffers are declared in global scope so they available in any point of your code.
 
alexvd:
Of course. Buffers are declared in global scope so they available in any point of your code.
...so I am wondering if it is actually possible to save on ram when using the same function multiple times. If I am using a buffer in a function, the logical implication is that multiple buffers are needed when using the same function and therefore using a lot of ram. The whole idea of functions is to save on ram!! Is it possible to have a local buffer? Should I be reading a C++ textbook?
 
Sorry, now you've got me thinking!! I suppose there should be a way to totally remove the buffer using another function with variables, although I have no idea how right at this moment!