iMAonarray problem in an expert advisor

 
Once again on iMAONARRAY.

The examples I have found of setting up arrays seem only to apply to indicators. My problem is with an expert advisor. I am not sure I have implemented the array properly, so I would be very grateful if you could double check the code I am using for an iMAOnArray in an expert advisor.

There are two arrays, and this is how I have set them up.

double RSI[];
ArrayResize(RSI,100);
ArraySetAsSeries(RSI,true);
double OBV[];
ArrayResize(OBV,100);
ArraySetAsSeries(OBV,true);
for(int i=100; i>=0; i--)
{
RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i));
OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i));
}

I then want to run MAs on the two arrays, as follows:
double Green0 = iMAOnArray(RSI,0,2,0,MODE_SMA,0);
double Green1 = iMAOnArray(RSI,0,2,0,MODE_SMA,1);
and
double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,0);
double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,1);

I do not seem to be able to get meaningful trades with this code. When I use Bars instead of 100, the EA cannot even complete one day of data. What am I doing wrong?

Thanks for your help.

Roy
 
Try
ArrayResize(RSI,101)
ArrayResize(OBV,101)

Your loop has 101 increments but there are only 100 locations in the array.

(this might not be the problem)
 
I'll give it a try, thanks. I guess that I have to make sure that i= is always a smaller number than the array size, is that the case?

What if I use Bars instead of a specific figure?
 
As long as the number of items you store in an array is less than or equal to the storage aloocated for the array you will be OK.

Bars changes, as the chart grows. you can keep resizing if you are filling the array, if you like.
 
Thanks for the clarification. I think that the code below is working. In any case I do get trades that seem sensible. I suppose that if I set ArrayResize to Bars, I would need to have i=Bars-1.

As I said, it seems to work this way, but I'm wondering if it isn't counting backwards. Under what circumstances would you have ArraySetAsSeries true, with i=0 and <=101, and i++??

Very grateful for the help.

47

double OBV[];
ArrayResize(OBV,101);
ArraySetAsSeries(OBV,false);
for(int i=100; i>=0; i--)
{
OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i));
}
double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,P_ZBar);
double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,(P_ZBar+1));
 
I'm fuzzy on the ArraySetAsSeries... Would have to experiment some...
Apparently it is needed if you are going to create an array, and operate on it
with the iXXXOnArray functions.

Here is where it is dicussed in the documentation -- https://www.mql5.com/en/search?utm_campaign=MQL4.community
 
I have problems following the documentation on MQL, and find I have to experiment in most cases before I get anything right. Perhaps a background in programming (which I don't have) would help.

The Documentation says the following about ArraySetAsSeries:

"Sets indexing direction of the array. If the set parameter has the TRUE value, the array will be indexed in a reversed order, i.e., the last element has a zero index. The FALSE value sets a standard indexing order. The function returns the previous status."

By this account, when you set as TRUE you need int i=0; i>=100; i++ since the last array element is 0 and in the ixxxonarray function you will count from zero backwards from 0 by +1 increments.

When you set as FALSE you need int int i=100; i>=0; i-- since the last array element is 100 and in the ixxxonarray function you will count backwards by -1 increments.

Which is the correct choice for use in an EA?

Or do I completely misunderstand this???

47
 
You need it when you use some built in functions to perform some "indicator" function on an array you create.

Look again at the link, the other times ArraySetAsSeries is mentioned is all related to iSomethingOnArray().

"do I completely misunderstand this???"

I don't know, just use it when they say you have to, which is when you are using one of the iSomethingOnArray()
functions.

Doesn't matter which way you count, up or down, as the function does one value at a time, unrelated to the count sequence.

Just put bar 0 into array[0] bar 1 into array[1] etc

for(int i=100; i>=0; i--)
{
RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i));
OBV[i] = (iOBV(NULL,0,PRICE_MEDIAN,i));
}

Your code should be fine
 
Thank you for your very helpful explanations. I appreciate your patience. I think the code is running properly, although I find it extremely slow when doing backtesting or optimizing.

47
 
An optimization here would be to reduce your array sizes to what is needed, instead of a size of 100 or 101 or Bars.
You can probably create and set the size once, it doesn't need to grow with what I see you doing.

Use two loops, one to minimally fill the RSI array, another to minimally fill the OBV, unless both use the same period, then use one loop as you do above.
 
Thanks again for your helpful suggestions. Let us say that I want to run xxxonArray on 3 different Indicators: RSI, OBV, Force. Then in each case, I assume that I would only need to fill the array with a number of elements equal to the longest period of the xxxonArray + 1. Is that correct? The code would look as below. Would this be efficient coding? Can I use any letters I wish instead of i,j,k?

Also If I use ArraySetAsSeries TRUE for an array of xx elements, then the loop should be (int i=0; i<=xx; i++). Is this correct?

Thanks,
47

double RSI[];
ArrayResize(RSI,35);
ArraySetAsSeries(RSI,false);
for(int i=34; i>=0; i--)
{
RSI[i] = (iRSI(NULL,0,13,PRICE_CLOSE,i));
}
double Green0 = iMAOnArray(RSI,0,2,0,MODE_SMA,0);
double Green1 = iMAOnArray(RSI,0,2,0,MODE_SMA,1);
double Red0 = iMAOnArray(RSI,0,7,0,MODE_SMA,0);
double Red1 = iMAOnArray(RSI,0,7,0,MODE_SMA,1);
double Yellow0 = iMAOnArray(RSI,0,34,0,MODE_SMA,0);
double Yellow1 = iMAOnArray(RSI,0,34,0,MODE_SMA,1);
double BlueUpp0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,0);
double BlueUpp1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_UPPER,1);
double BlueLow0 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,0);
double BlueLow1 = iBandsOnArray(RSI,0,34,1.6185,0,MODE_LOWER,1);

double OBV[];
ArrayResize(OBV,14);
ArraySetAsSeries(OBV,false);
for(int j=13; j>=0; j--)
{
OBV[j] = (iOBV(NULL,0,PRICE_MEDIAN,j));
}
double OBV0 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,0);
double OBV1 = iMAOnArray(OBV,0,P_OBVPer,0,P_OBVMode,1);

double Force[];
ArrayResize(Force,14);
ArraySetAsSeries(Force,false);
for(int k=13; k>=0; k--)
{
Force[k]= (iForce(NULL,0,MODE_SMMA,PRICE_TYPICAL,k));
}
double FFast0 = iMAOnArray(Force,0,2,0,MODE_EMA,0);
double FFast1 = iMAOnArray(Force,0,2,0,MODE_EMA,1);
double FSlow0 = iMAOnArray(Force,0,13,0,MODE_EMA,0);
double FSlow1 = iMAOnArray(Force,0,13,0,MODE_EMA,1);
Reason: