Nested For Loop and an Array of sums of another array

 

I am trying to create an array which has as values the rolling sum of another array.  In this case, I am trying to create a new array (CumulativeArray) where each value is a rolling sum of 20 values of Array.

Below, I have a snippet of code that I am hoping says the following:

CumulativeArray[0]=Array[0]+Array[1]+...+Array[19]

CumulativeArray[1]=Array[1]+Array[2]+...+Array[20].

for(int i=0; i<=ArraySize(Array)-19;i++)
        {
        for(int j=i;j<=i+19;j++)
                {
                CumulativeArray[i]+=Array[j];
                }
        }

I'm having trouble trying to think through how I should structure my indices.  Say Array has 1000 values.  I want 

CumulativeArray[981]=Array[981]+Array[982]+...+Array[1000]


However, when I attempt to write this code, I am getting a null value error (all my values are 2147483647).

Here is the specific project I am working on:


#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Yellow

extern int Length=200;
                       
double Vol[];
double VolumeRatio[];
double PriceVolumeRatio[];
double CumulativePriceVolumeRatio[];
double CumulativeVolumeRatio[];
double VAMA[];

int init()
   {
      IndicatorShortName("VAMA following Fidelity Formula ");
      IndicatorDigits(Digits);
      SetIndexStyle(0,DRAW_NONE);
      SetIndexBuffer(0,Vol);
      SetIndexStyle(1,DRAW_NONE);
      SetIndexBuffer(1,VolumeRatio);
      SetIndexStyle(2,DRAW_NONE);
      SetIndexBuffer(2,PriceVolumeRatio);
      SetIndexStyle(3,DRAW_NONE);
      SetIndexBuffer(3,CumulativePriceVolumeRatio);
      SetIndexStyle(4,DRAW_NONE);
      SetIndexBuffer(4,CumulativeVolumeRatio);
      SetIndexStyle(5,DRAW_NONE);
      SetIndexBuffer(5,VAMA);
      return(0);
   }

int deinit()
  {
      return(0);
  }
 

int start()
   {
      int limit=Bars-1;
      int pos = limit;
      int pos2 = pos;
      
      //Create a Volume Array across all bars.
      while(limit>=0)
      {
 
         Vol[limit]=iVolume(NULL,NULL,limit);
         limit--;
      }
     
      //Take average of Volume Array.
      double VolArraySum;
      int limitarray = ArraySize(Vol)-1;
      for(limitarray;limitarray>=0;limitarray--)
        {
        VolArraySum +=Vol[limitarray];
        }
        
      //Calculate the Volume Increment.
      double VolumeIncrement = VolArraySum/ArraySize(Vol)*.67;

      //Alert(VolumeIncrement);
      //Use to test VolumeIncrement
      
      //Calculate the VolumeRatio and Price Volume Ratio across all bars.
      while(pos>=0)
      {
      VolumeRatio[pos]=Vol[pos]/VolumeIncrement;
      PriceVolumeRatio[pos]=VolumeRatio[pos]*iClose(NULL,NULL,pos);
      pos--;
      }
      //Calculate the cumulative price volume ratio.  Calculate the Length average.
      int i;
      int j;
      for(i=0;i<=ArraySize(PriceVolumeRatio)-Length;i++)
         {
         for(j=i+1;j<=i+Length;j++)
            {
            CumulativePriceVolumeRatio[i]+=PriceVolumeRatio[j];
            }
         }
  return(0);
   }

There is probably a more efficient way to write this code, but I'm writing it out in as many steps as possible.  This indicator is also incomplete, as there are buffers I am not yet using since I am stuck on this step.

 
gershgorin:

I am trying to create an array which has as values the rolling sum of another array.  In this case, I am trying to create a new array (CumulativeArray) where each value is a rolling sum of 20 values of Array.

Your loops are wrong, you are adding the same 20 items everytime and the outside loop is incorrectly sized on the data array.

In your example you need to have the cumulative array on the outside loop and use a pointer on the inside to move 20 positions on or, a calculated start value for the inner loop based upon the index of the CumulativeArray.

Use more meaningful names for data variables it will help you understand your program flow easier.

See example script below.

//#property strict

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{

   double CumulativeArray [10];
   double DataArray[200];
   int iPointer = 0;
   for(int x=0; x<200; x++)  
      DataArray[x] = x;       // seed values for demo  

   for(int c_count=0 ; c_count<ArraySize(CumulativeArray); c_count++)  
   {
      
      for(int d_count=0; d_count<20; d_count++)
      {
         CumulativeArray[c_count] += DataArray[d_count + iPointer];
      }
      iPointer += 20;
      Print("C-" + c_count + "  = " + CumulativeArray[c_count]);
   }
}

	          
 
Paul Anscombe #:

Your loops are wrong, you are adding the same 20 items everytime and the outside loop is incorrectly sized on the data array.

In your example you need to have the cumulative array on the outside loop and use a pointer on the inside to move 20 positions on or, a calculated start value for the inner loop based upon the index of the CumulativeArray.

Use more meaningful names for data variables it will help you understand your program flow easier.

See example script below.

Thanks for your feedback.

I will give this a try when I get home.  I notice that in my hypothetical I was mentioning 20.  This was just to build some intuition.  The indicator actually uses a Length of 200.  In this scenario, would iPointer+=200?

Basically this is a 200 period volume adjusted moving average.

 
gershgorin #:

Thanks for your feedback.

I will give this a try when I get home.  I notice that in my hypothetical I was mentioning 20.  This was just to build some intuition.  The indicator actually uses a Length of 200.  In this scenario, would iPointer+=200?

Basically this is a 200 period volume adjusted moving average.

If that is the case then there are smarter ways you only need to add 200 numbers once then make delta changes
 
Paul Anscombe #:
If that is the case then there are smarter ways you only need to add 200 numbers once then make delta changes


I modified the code (below).  I understand what my code is doing until we get to the cumulative step.  Because there are a lot of bars in the chart, I would need the CumulativePriceVolumeRatio to be at least Bars-Length-1 long (since 0 to 199 is 200 values).  I understand that the external loop will fix a place on the CumulativePriceVolumeRatio array.  The second loop will then need to iterate across 200 values of PriceVolumeRatio (which spans all the bars in the chart).  I'm thinking of this as the base case.  If i=0, then CumulativePriceVolumeRatio[0]+=PriceVolumeRatio[j+iPointer] where j sums through 0 to 199 and places this CumulativePriceVolumeRatio[0].  Then for CumulativePriceVolumeRatio[1], this should sum across j=1 to j=200. 


I'm not sure why the code below isn't accomplishing the task.  My go to check is just seeing how the indices behave.  If i=0, then j ranges from 0 to 199.  If i=1, then j ranges from 1 to 200.   

I was thinking about your example, wouldn't that only work if there is a fixed amount of data?

The eventual goal is to replicate the calculation provided here: http://www.neuroshell.com/manuals/ais1/index.html?vama.htm&nbsp;and 

So far, at the 200th bar, I get the numerical NULL value output.


      int i;
      int j;
      for(i=0;i<=Bars-Length-1;i++)
         {
         for(j=i;j<=i+Length-1;j++) 
            {
            CumulativePriceVolumeRatio[i]+=PriceVolumeRatio[j]; //Cumulative sum of all PriceVolumeRatios
            }
         }


Provided below is the indicator code in all of it's context.  The default length is 200.


#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Yellow

extern int Length=200;
                       
double Vol[];
double VolumeRatio[];
double PriceVolumeRatio[];
double CumulativePriceVolumeRatio[];
double CumulativeVolumeRatio[];
double VAMA[];

int init()
   {
      IndicatorShortName("VAMA following Fidelity Formula ");
      IndicatorDigits(Digits);
      SetIndexStyle(0,DRAW_NONE);
      SetIndexBuffer(0,Vol);
      SetIndexStyle(1,DRAW_NONE);
      SetIndexBuffer(1,VolumeRatio);
      SetIndexStyle(2,DRAW_NONE);
      SetIndexBuffer(2,PriceVolumeRatio);
      SetIndexStyle(3,DRAW_NONE);
      SetIndexBuffer(3,CumulativePriceVolumeRatio);
      SetIndexStyle(4,DRAW_NONE);
      SetIndexBuffer(4,CumulativeVolumeRatio);
      SetIndexStyle(5,DRAW_NONE);
      SetIndexBuffer(5,VAMA);
      return(0);
   }

int deinit()
  {
      return(0);
  }
 

int start()
   {
      int limit=Bars-1;
      int pos = limit;
      int pos2 = pos;
      
      //Create a Volume Array across all bars.
      while(limit>=0)
      {
 
         Vol[limit]=iVolume(NULL,NULL,limit);
         limit--;
      }
     
      //Take average of Volume Array.
      double VolArraySum;
      int limitarray = ArraySize(Vol)-1;
      for(limitarray;limitarray>=0;limitarray--)
        {
        VolArraySum +=Vol[limitarray];
        }
        
      //Calculate the Volume Increment.
      double VolumeIncrement = VolArraySum/ArraySize(Vol)*.67;

      //Alert(VolumeIncrement);
      //Use to test VolumeIncrement
      
      //Calculate the VolumeRatio and Price Volume Ratio across all bars.
      while(pos>=0)
      {
      VolumeRatio[pos]=Vol[pos]/VolumeIncrement;
      PriceVolumeRatio[pos]=VolumeRatio[pos]*iClose(NULL,NULL,pos);
      pos--;
      }
      //Calculate the cumulative price volume ratio.  Calculate the Length average.
      int i;
      int j;
      for(i=0;i<=Bars-Length-1;i++)
         {
         for(j=i;j<=i+Length-1;j++) 
            {
            CumulativePriceVolumeRatio[i]+=PriceVolumeRatio[j];
            }
         }
  return(0);
   }