# Passing and Accessing Multidimensional Array in a Function

## Before the days of OOEL and more advanced data structures, such as vectors, you had to work with multidimensional arrays.

The problem with arrays is you have to do all the housekeeping whereas with vectors the housekeeping is handled internally.  Yes, vectors in many cases would be the most efficient approach, but if you are already using Multi-D arrays, then mixing the two could become confusing.  So stick with the arrays for now and progress into vectors at your leisure.

### Recreate the CCI indicator with Multi-D Array

This exercise is for demonstration purposes only as the existing CCI function works just fine.  However, when you are trying out something new  or in this case an application of a different data structure (array) its always great to check your results against a known entity.  If your program replicates the known entity, then you know that you are close to a solution.  The CCI function accesses data via the global High, Low and Close data streams and then applies a mathematical formula to derive a result. <

Create the function first by prototyping what the function will need in the formal parameter list (funciton header).   The first thing the function will need is the data – here is what it will look like.

• OHLCArray[1,1] =  1210903.00 // DATE
• OHLCArray[1,2] =    4420.25 // OPEN
• OHLCArray[1,3] =    4490.25 // HIGH
• OHLCArray[1,4] =    4410.25 // LOW
• OHLCArray[1,5] =    4480.75 // CLOSE
• OHLCArray[2,1] =  1210904.00 // DATE
• OHLCArray[2,2] =    4470.25 // OPEN
• OHLCArray[2,3] =    4490.25 // HIGH
• OHLCArray[2,4] =    4420.25 // LOW
• OHLCArray[2,5] =    4440.75 // CLOSE

### Visualize 2-D Array as a Table

 Column 1 Column 2 Column 3 Column 4 Column 5 1210903 44202.25 4490.25 4410.25 4480.75 1210904 4470.25 4490.25 4420.25 4440.76
The CCI function is only concerned with H, L, C and that data is in columns 3, 4, 5.  If you know the structure of the array before you program the function, then you now which columns or fields you will need to access.  If you don’t know the structure beforehand , then that information would need to be passed into the function as well.   Let us assume we know the structure.  Part of the housekeeping that I mentioned earlier was keeping track of the current row where the latest data is being stored.  This “index” plus the length of the CCI indicator is the last two things we will need to know to do a proper calculation.

### CCI_2D Function Formal Parameter List

``// This function needs data, current data row, and length// Notice how I declare the OHLCArray using the dummy X and Y// Variable - this just tells TradeStation to expect 2-D array// ------------------//                | |//                * *inputs: OHLCArray[x,y](numericArray), currentRow(numericSimple), length(numericSimple);//                         ***//                         |||//----------------------------// Also notice I tell TradeStation that the array is of type numeric// We are not changing the array but if we were, then the type would be // numericArrayRef - the actual location in memory not just a copy 	``
CCI_2D Formal Parameter List

#### 2-D Array Must Run Parallels with Actual Data

The rest of the function expects the data to be just like the H, L, C built-in data – so there cannot be gaps.  This is very important when you pack the data and  you will see this in the function driver code a.k.a an indicator. The data needs to align with the bars.  Now if you are using large arrays this can slow things down a bit.  You can also shuffle the array and keep the array size to a minimum and I will post how to do this in a post later this week.  The CCI doesn’t care about the order of the H,L,C as long as the last N element is the latest values.

``variables: 		Mean( 0 ),sum1(0),sum2(0), 	AvgDev( 0 ),rowNum(0), 	Counter( 0 ) ;AvgDev = 0 ;if currentRow > length then // make sure enough rowsbegin	sum1 = 0;	sum2 = 0;	for rowNum = currentRow  - (length-1) to currentRow	begin		value1 = OHLCArray[rowNum,3];		value2 = OHLCArray[rowNum,4];		value3 = OHLCArray[rowNum,5];		sum1 = sum1 + value1 + value2 + value3;	end;	//Mean = Average( H + L + C, Length ) ; { don't have to divide H+L+C by 3, cancels out } 	Mean = sum1/length;	print(d," Mean ",mean," ",mean/3);		for rowNum = currentRow - (length-1) to currentRow	begin		value1 = OHLCArray[rowNum,3];		value2 = OHLCArray[rowNum,4];		value3 = OHLCArray[rowNum,5];		sum2 = sum2 + AbsValue((value1 + value2 + value3) - Mean);	end ;	//	AvgDev = AvgDev + AbsValue( ( H + L + C )[Counter] - Mean ) ;	AvgDev = sum2 / Length ;	print(d," avgDev ",AvgDev," ",AvgDev/3);	value1 = OHLCArray[currentRow,3];	value2 = OHLCArray[currentRow,4];	value3 = OHLCArray[currentRow,5];end;if AvgDev = 0 then	CCI_2D = 0else	CCI_2D = ( value1 + value2 + value3 - Mean ) / ( .015 * AvgDev ) ;``
CCI-2D Function
This function could be streamlined, but I wanted to show you how to access the different data values with the currentRow variable and columns 3, 4, and 5.  I extract these data and store them in Values variables.  Notice the highlighted line where I check to make sure there are enough rows to handle the calculation.  If you try to access data before row #1, then you will get an out of bounds error and a halt to program execution.

### Function Driver in the form of an Indicator

``array: OHLCArray[5000,5](0);Inputs: CCI2DLen(14),CCILen(14);vars: numRows(0),myCCI(0),regCCI(0);numRows = numRows + 1;OHLCArray[numRows,1] = d;OHLCArray[numRows,2] = o;OHLCArray[numRows,3] = h;OHLCArray[numRows,4] = l;OHLCArray[numRows,5] = c;myCCI = CCI_2D(OHLCArray,numRows,14);regCCI = CCI(14);plot1(myCCI," CCI_2D ");plot2(regCCI," CCI ");``
CCI-2D Indicator

Notice lines 16 and 17 where I am plotting both function results – my CCI_2D and CCI.   Also notice how I increment numRows on each bar – this is the housekeeping that keeps that array synched with the chart.  In the following graphic I use 14 for CCI_2D and 9 for the built-in CCI.