Is iMAOnArray() 'broken'.....?

 

Hi. Can anyone confirm that iMAOnArray doesn't function properly in all instances? There is no problem using it with a fully populated array but when it is included in the 'loop' it does not work - see below. Can anyone explain why?

for (int i=limit; i>=0; i--)

{

MAbuffer = iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_CLOSE,i);

MAvgBuffer1 = iMAOnArray(MAbuffer,0,MAvg_Period,0,MA_Type,i);

}[/CODE]

Another thing that 'bothers' me is the 'Total' parameter. What use is it? When iMAOnArray is used normally, it must always be set to zero (or the array length) or it won't work. The only situation I can see it being needed is if iMAOnArray operated by creating an array of 'Total' elements and returning a pointer to this - but it doesn't... Finally, can anyone explain why the following function doesn't work correctly. It calculates the SMA perfectly but the other MA types don't appear to be exactly as they should be.

[CODE]double My_MAOnArray(double Array[], int Start, int Count, int MA_Type)

{

double TempArray[],Avg;

ArraySetAsSeries(TempArray,true);

ArrayResize(TempArray,Count);

for (int i=Count; i>=0; i--)

TempArray = Array[Start + i];

Avg = iMAOnArray(TempArray,0,Count,0,MA_Type,0);

return(Avg);

}

After 'Googling' through every link I could find, there seem to be quite a few people who think this function does not work properly and I tend to agree. Any and all comments are welcome.

 
for (int i=limit; i>=0; i--)

{

MAbuffer = iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_CLOSE,i);

MAvgBuffer1 = iMAOnArray(MAbuffer,0,MAvg_Period,0,MA_Type,i);

}[/code]

You must complete one array before you can use it to construct another as in

for (int i=limit; i>=0; i--)

{

MAbuffer = iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_CLOSE,i);

}

for (int i=limit; i>=0; i--)

{

MAvgBuffer1 = iMAOnArray(MAbuffer,0,MAvg_Period,0,MA_Type,i);

}

[/code]

[code]double My_MAOnArray(double Array[], int Start, int Count, int MA_Type)

{

double TempArray[],Avg;

ArraySetAsSeries(TempArray,true);

ArrayResize(TempArray,Count);

for (int i=Count; i>=0; i--)

TempArray = Array[Start + i];

Avg = iMAOnArray(TempArray,0,Count,0,MA_Type,0);

return(Avg);

}

on the second count you have to write the code completly and assign it to a buffer as in

[code]

ArrayResize( PriceTrend, 200 );

ArrayInitialize( PriceTrend, 0 );

ArraySetAsSeries( PriceTrend, True );

do what you want with PriceTrend array then

SetIndexBuffer( 0, PriceTrend );

it will plot on the charts

 

Mis B. Havin', I appreciate the response. I have no problem using iMAOnArray the 'normal' way but was trying to determine if it was possible to include it in the main program loop. Personally I think it is a poorly implemented function if it is necessary to define a separate loop in order to use it. Even my poor first attempt 'My_iMAOnArray' will work from within the main loop - ie.

for (int i=limit; i>=0; i--)

{

MAbuffer = iMA(NULL,0,MA_Period,0,MODE_SMA,PRICE_CLOSE,i);

MAvgBuffer1 = My_iMAOnArray(MAbuffer,i,MAvg_Period,MA_Type);

}

Incidently, my function 'My_iMAOnArray' works fine to the extent that it returns values to the calling suboutine which when written to a display buffer produces nice waveforms. The problem I was having with it was that when I superimposed another signal over this using the bog-standard for-iMAOnArray loop and using identical parameters, the signal produced by 'My_iMAOnArray' is not overwritten exactly as it should be except when 'ME_Type' = SMA (EMA, SMMA, LWMA aren't overwritten exactly).

And finally, as I suggested in the opening post, the 'Total' parameter in iMAOnArray appears to me more or less useless - especially if the function must be used in an independent loop. Having 'programmed around' what I deem shortcomings of iMAOnArray till now, I was hoping someone could set me straight

 

Just in case anyone is even remotely interested in what I'm talking about, here is a little indicator that draws three MAs. The blue one is 'MAbuffer' which is simply a SMA of the open chart. The gray and olive signals are MAs of MAbuffer, titled MAvgBuffer1 and MAvgBuffer2, MAvgBuffer1 being generated by My_iMAOnArray and MAvgBuffer2 by the built-in iMAOnArray function. When the indicator is first run, MAvgBuffer1 and MAvgBuffer2 are drawing SMAs of MAbuffer which works OK and results in only two signals being visible in the window (as one is plotted over the other). Changing MA_Type results in all three signals being visible which means there is either a problem with my code (the most likely reason) or iMAOnArray does not work properly........

Files:
 

Hi Omlette,

I agree that iMAOnArray is very quirky. I do not know why the entire source array needs to be populated before calling the function since one would think that you should not need the entire source dataset to calculate a moving average for a given bar.

With regard to your code, try this...

double My_MAOnArray(double Array[], int Start, int Count, int MA_Type)

{

double TempArray[],Avg;

int size;

size = ArraySize(Array) - Start;

ArraySetAsSeries(TempArray,true);

ArrayResize(TempArray,size);

for (int i=size; i>=0; i--)

TempArray = Array[Start + i];

Avg = iMAOnArray(TempArray,0,Count,0,MA_Type,0);

return(Avg);

}

The EMA, SSMA and LWA values returned by My_MAOnArray should then match those returned by iMAOnArray. The problem with your code is that the TempArray needs to be populated with all the source values prior to Bar not just the values for the Count variable.

I'd be interested to know if you were ever able to get to the bottom of the quirks of iMAOnArray.

Regards,

Laurence.

 

Laurence, thanks for taking the time to correct my code. Yes, an unfortunate instance of variable naming on my part - chosing 'Lperiod' instead of 'Count' would have saved me so much fustration

To answer your question, no I never made any further progress with iMAOnArray. Personally I think it is one of those functions that, though not exactly still-born, arrived damaged and is unlikely to fulfill its true potential

 

Question on iMAOnArray again

I tried to use indicator "Heiken_Ashi_Smoothed" in an EA. When I backtested it, it seems use lots of memory and very slow.

So I am trying to write a method (or a function ) as below in the EA to directly calculate the value of indicator. Unfortunately, I could not make it work. In the test, array

ExtMapBuffer5[], ExtMapBuffer6[], ExtMapBuffer7[], and ExtMapBuffer8[]

are printed out and not zero, but ExtMapBuffer1, ExtMapBuffer2, ExtMapBuffer3 and ExtMapBuffer4 are always printed out as zero. Do not understand why. Can any one help me to make it work?

Thank you very much

======================================================

//Heiken_Ashi_Smoothed

double Heiken_Ashi_Smoothed (int timeFrame, int MaMetod, int MaPeriod, int MaMetod2, int MaPeriod2, int order, int shift)

{

//---- buffers

double ExtMapBuffer1;

double ExtMapBuffer2;

double ExtMapBuffer3;

double ExtMapBuffer4;

double ExtMapBuffer5[];

double ExtMapBuffer6[];

double ExtMapBuffer7[];

double ExtMapBuffer8[];

double maOpen, maClose, maLow, maHigh;

double haOpen, haHigh, haLow, haClose;

int size=shift;

ArraySetAsSeries(ExtMapBuffer5,true);

ArrayResize(ExtMapBuffer5,size);

ArraySetAsSeries(ExtMapBuffer6,true);

ArrayResize(ExtMapBuffer6,size);

ArraySetAsSeries(ExtMapBuffer7,true);

ArrayResize(ExtMapBuffer7,size);

ArraySetAsSeries(ExtMapBuffer8,true);

ArrayResize(ExtMapBuffer8,size);

int pos = shift;

int pos2=pos;

while(pos>=0)

{

maOpen=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_OPEN,pos);

maClose=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_CLOSE,pos);

maLow=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_LOW,pos);

maHigh=iMA(NULL,0,MaPeriod,0,MaMetod,MODE_HIGH,pos);

haOpen=(ExtMapBuffer5[pos+1]+ExtMapBuffer6[pos+1])/2;

haClose=(maOpen+maHigh+maLow+maClose)/4;

haHigh=MathMax(maHigh, MathMax(haOpen, haClose));

haLow=MathMin(maLow, MathMin(haOpen, haClose));

if (haOpen<haClose)

{

ExtMapBuffer7[pos]=haLow;

ExtMapBuffer8[pos]=haHigh;

}

else

{

ExtMapBuffer7[pos]=haHigh;

ExtMapBuffer8[pos]=haLow;

}

ExtMapBuffer5[pos]=haOpen;

ExtMapBuffer6[pos]=haClose;

Print ("ExtMapBuffer5[", pos, "]=", ExtMapBuffer5[pos]);

Print ("ExtMapBuffer6[", pos, "]=", ExtMapBuffer6[pos]);

Print ("ExtMapBuffer7[", pos, "]=", ExtMapBuffer7[pos]);

Print ("ExtMapBuffer8[", pos, "]=", ExtMapBuffer8[pos]);

pos--;

}

ExtMapBuffer1=iMAOnArray(ExtMapBuffer7,Bars,MaPeriod2,0,MaMetod2,pos2);

ExtMapBuffer2=iMAOnArray(ExtMapBuffer8,Bars,MaPeriod2,0,MaMetod2,pos2);

ExtMapBuffer3=iMAOnArray(ExtMapBuffer5,Bars,MaPeriod2,0,MaMetod2,pos2);

ExtMapBuffer4=iMAOnArray(ExtMapBuffer6,Bars,MaPeriod2,0,MaMetod2,pos2);

Print ("ExtMapBuffer1=", ExtMapBuffer1);

Print ("ExtMapBuffer2=", ExtMapBuffer2);

Print ("ExtMapBuffer3=", ExtMapBuffer3);

Print ("ExtMapBuffer4=", ExtMapBuffer4);

if (order==0) return (ExtMapBuffer1);

else if (order==1) return (ExtMapBuffer2);

else if (order==2) return (ExtMapBuffer3);

else if (order==3) return (ExtMapBuffer4);

}

=======================================================