| / | Forum |
|
MaxPayne
2007.11.04 15:13
Dear Fellow-MQL-Afficionados!
I started with MQL4 for about two months and have been carrying out some more or less successful experiments. However, I keep running into problems as soon as I try to use the function: iMAOnArray! In order to try to really understand this function I did some experiments and I'm still baffled. The documentation states the following:
I have yet to see an example that uses something else than 0 for total and the exact difference between ma_shift and shift is not at all clear. Now over to my example. Initially, I wanted to code the following in an EA but had problems, therefore I converted it into an indicator first in order to better observe its behaviour. The HiLo-indicator determines the highest highs and lowest lows in a certain period and then applies a moving average to these values. The complete code is as follows: //+------------------------------------------------------------------+ //| MP_HiLo.mq4 | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 4 #property indicator_color1 SteelBlue // highs #property indicator_color2 SteelBlue // lows #property indicator_color3 Tomato // avg. highs #property indicator_color4 Tomato // avg. lows #property indicator_width1 1 #property indicator_width2 1 #property indicator_width3 1 #property indicator_width4 1 //---- input parameters extern int maMethod = MODE_SMA; extern int period = 15; //---- buffers double low[]; double high[]; double avgHigh[]; double avgLow[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { string short_name; //---- 0 additional buffer used for counting. IndicatorBuffers(4); //---- indicator line SetIndexStyle(0, DRAW_LINE); SetIndexBuffer(0, low); SetIndexLabel(0, "Lows"); SetIndexDrawBegin(0, 1); SetIndexStyle(1, DRAW_LINE); SetIndexBuffer(1, high); SetIndexLabel(1, "Highs"); SetIndexDrawBegin(1, 1); SetIndexStyle(2, DRAW_LINE); SetIndexBuffer(2, avgHigh); SetIndexLabel(2, "Avg. Highs"); SetIndexDrawBegin(2, 1); SetIndexStyle(3, DRAW_LINE); SetIndexBuffer(3, avgLow); SetIndexLabel(3, "Avg. Lows"); SetIndexDrawBegin(3, 1); //---- name for DataWindow and indicator subwindow label short_name = "MP_HiLo(" + period + "," + maMethod + ")"; IndicatorShortName(short_name); //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| Highs and Lows | //+------------------------------------------------------------------+ int start() { int i; int limit; int length; double atrValue; int countedBars = IndicatorCounted(); // signal error when the number of counted bars is negative if (countedBars < 0) { return(-1); } limit = Bars - countedBars - 1; //---- loop over all bars that need to be updated for (i = limit - 1; i >= 0; i--) { high[i] = High[iHighest(NULL, 0, MODE_HIGH, period, i + 1)]; low[i] = Low[iLowest(NULL, 0, MODE_LOW, period, i + 1)]; /* } for (i = limit - 1; i >= 0; i--) { */ length = period; if (i + period > Bars) { length = Bars - i - 1; } avgHigh[i] = iMAOnArray(high, 0, length, 0, maMethod, i); avgLow[i] = iMAOnArray(low, 0, length, 0, maMethod, i); } //---- end of loop return(0); } //+------------------------------------------------------------------+If I run this indicator right after compilation it delivers the expected result: ![]() However, as soon as I change the period (here from 15 to 20) only the first 20 values are valid, all others are a very large number. ![]() I know I can get the desired behaviour if I first complete the high and low buffers by changing the code into two loops. for (i = limit - 1; i >= 0; i--) { high[i] = High[iHighest(NULL, 0, MODE_HIGH, period, i + 1)]; low[i] = Low[iLowest(NULL, 0, MODE_LOW, period, i + 1)]; } for (i = limit - 1; i >= 0; i--) { length = period; if (i + period > Bars) { length = Bars - i - 1; } avgHigh[i] = iMAOnArray(high, 0, length, 0, maMethod, i); avgLow[i] = iMAOnArray(low, 0, length, 0, maMethod, i); } //---- end of loopHowever, if I'm coding an EA I also have to react on every new value by itself so the double loop is not the desired solution. Through experiments I have found out that coding the shift in ma_shift instead of shift does exactly what I want, but takes an enormous amount of recalculation time. (Essentially locks up the computer for a while!). //---- loop over all bars that need to be updated for (i = limit - 1; i >= 0; i--) { high[i] = High[iHighest(NULL, 0, MODE_HIGH, period, i + 1)]; low[i] = Low[iLowest(NULL, 0, MODE_LOW, period, i + 1)]; length = period; if (i + period > Bars) { length = Bars - i - 1; } avgHigh[i] = iMAOnArray(high, 0, length, i, maMethod, 0); avgLow[i] = iMAOnArray(low, 0, length, i, maMethod, 0); } //---- end of loop So one of the MQL-Experts please help me out on this one and help me understand why things are working out as they are (and obviously not as I expected them to). QUESTION: How can I calculate the averages in the same loop as the highs and lows are determined (without locking up the computer)? The essential values for the calculation of the average are available so I don't see a reason to construct two loops! Thanks in advance! Max Payne |
|
Technical Analysis: Make the Impossible Possible! The article answers the question: Why can the impossible become possible where much suggests otherwise? Technical analysis reasoning. |
|
phy
2007.11.04 19:10
total -- not sure, would have to play with it to find out what it means shift -- the bar number for which the indicator returns the calculated value ma_shift -- moves the "result" of the calculation to a different bar. Open a chart, add Moving Average indicator. in properties, a negative shift moves the MA line to the left, a positive shift moves it to the right. ----- I too have needed to use two loops to get valid values when using arrays. |
|
MaxPayne
2007.11.04 19:56
Hi Phy,
thanks for your rapid reply! I will try to investigate the ma_shift result as you explained it and check whether the line is shifted in the output. Have you been able to use iMAOnArray in EAs? Cheers! Max Payne
|
|
phy
2007.11.04 20:10
I don't see where I used it in an EA... Used in varrious Indicators and one Script. No reason it shouldn't be usable in EA. $ grep -EiR imaonarray * Binary file MetaEditor.exe matches experts/indicators/Accelerator.mq4: ExtBuffer4[i]=iMAOnArray(ExtBuffer3,Bars,5,0,MODE_SMA,i); experts/indicators/adx.mq4: PlusDiBuffer[i]=iMAOnArray(PlusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i); experts/indicators/adx.mq4: MinusDiBuffer[i]=iMAOnArray(MinusSdiBuffer,Bars,ADXPeriod,0,MODE_EMA,i); experts/indicators/adx.mq4: ADXBuffer[i]=iMAOnArray(TempBuffer,Bars,ADXPeriod,0,MODE_EMA,i); experts/indicators/ATR-JMA.mq4: AtrBuffer[i]=iMAOnArray(TempBuffer,Bars,AtrPeriod,0,MODE_SMA,i); experts/indicators/ATR.mq4: AtrBuffer[i]=iMAOnArray(TempBuffer,Bars,AtrPeriod,0,MODE_SMA,i); experts/indicators/colorOsMA.mq4: SignalBuffer[i]=iMAOnArray(MACDBuffer,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/Ergodic.mq4: s_ema1_Buffer[i]=iMAOnArray(Price_Delta1_Buffer,Bars,s,0,MODE_EMA,i); experts/indicators/Ergodic.mq4: s_ema2_Buffer[i]=iMAOnArray(Price_Delta2_Buffer,Bars,s,0,MODE_EMA,i); experts/indicators/Ergodic.mq4: u_ema1_Buffer[i]=iMAOnArray(s_ema1_Buffer,Bars,u,0,MODE_EMA,i); experts/indicators/Ergodic.mq4: u_ema2_Buffer[i]=iMAOnArray(s_ema2_Buffer,Bars,u,0,MODE_EMA,i); experts/indicators/Ergodic.mq4: ema_ErgBuffer[i] = iMAOnArray(ErgBuffer,Bars,smooth,0,MODE_EMA,i); experts/indicators/HMA2color.mq4:ExtMapBuffer[x] = iMAOnArray(vect, 0, p, 0, method, x); experts/indicators/Hull Moving Average.mq4: ExtMapBuffer[i] = iMAOnArray(vect, 0, sqrtPeriod, 0, method, i); experts/indicators/HullTrend.mq4: ind_buffer0[i]=iMAOnArray(ind_buffer1,0,MathFloor(MathSqrt(HMA_Period)),0,MODE_LWMA,i+Displacement); experts/indicators/JMA_MACD.mq4: ind_buffer2[i]=iMAOnArray(ind_buffer1,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/JMA_MACD_Color.mq4: tempSignalLine=iMAOnArray(ind_buffer5,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/MACD.mq4: SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/MACD_Color-1.mq4: ind_buffer3[i]=iMAOnArray(temp,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/MACD_Color.mq4: ind_buffer3[i]=iMAOnArray(temp,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/OsMA.mq4: SignalBuffer[i]=iMAOnArray(MacdBuffer,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/PhyTrade__SlopeIndicator.mq4: downSlopeValue = iMAOnArray( array0, 0, maPeriod, 0, 0, i) ; experts/indicators/PhyTrade__SlopeIndicator.mq4: upSlopeValue = iMAOnArray( array1, 0, maPeriod, 0, 0, i) ; experts/indicators/PhyTrade__SlopeIndicator.mq4: double imaArray0 = MathAbs(iMAOnArray(array0,0,maPeriod,0,0,i)); experts/indicators/PhyTrade__SlopeIndicator.mq4: double imaArray1 = MathAbs(iMAOnArray(array1,0,maPeriod,0,0,i)); experts/indicators/PhyTrade__Volume_Normalized.mq4: oldVolumeAverage[i] = iMAOnArray(oldVolumeCounts, 0, 13,0, MODE_LWMA, i); experts/indicators/Phy__ATR.mq4: AtrBufferSlow[i] = iMAOnArray(TempBuffer,Bars,AtrPeriodSlow,0,MODE_SMA,i); experts/indicators/Phy__ATR.mq4: AtrBufferFast[i] = iMAOnArray(TempBuffer,Bars,AtrPeriodFast,0,MODE_SMA,i); experts/indicators/Phy__Average_Up-Chart.mq4: //average = iMAOnArray( maBuffer, 2000, maPeriod, 0, MODE_EMA, i); experts/indicators/Phy__Average_Up-Chart.mq4: bufferMA[i] = iMAOnArray( UpBuffer1, Bars, 13, 0, MODE_SMA, i); experts/indicators/Phy__Average_Up-Chart.mq4: UpBuffer3[i] = iMAOnArray( UpBuffer1, Bars, 34, 0, MODE_SMA, i); experts/indicators/Phy__BarAverageSize.mq4: size[i] = iMAOnArray( rawSize, 0, maPeriod, maShift, maMethod, i); experts/indicators/Phy__Bar_Height_Period.mq4: //display[i] = iMAOnArray(barHeight, 0, 13, 0, MODE_EMA, i); experts/indicators/Phy__Bar_Height_Period.mq4: display[i] = iMAOnArray(barHeight, 0, period, 0, MODE_EMA, i); experts/indicators/Phy__CCI.mq4: TypicalPriceMovingAverage[i] = iMAOnArray(TypicalPrice, 0, cciPeriod, maShift, maMethod, i); experts/indicators/Phy__MACD_Color.mq4: ind_buffer3[i]=iMAOnArray(temp,Bars,SignalSMA,0,MODE_SMA,i); experts/indicators/Phy__Pivots_Floating.mq4: average[i] = iMAOnArray(middle, 0, ma_period, 0, ma_method, i); experts/indicators/Phy__Stochastic.mq4: SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod,0,MODE_SMA,i); experts/indicators/Phy__Stochastic1.mq4: SignalBuffer[i] = iMAOnArray(MainBuffer, Bars, DPeriod, 0, MODE_SMA, i); experts/indicators/Phy__Stochastic2.mq4: KBuffer[i] = iMAOnArray(KFast, 0, SlowPeriod, 0, MODE_SMA, i); experts/indicators/Phy__Stochastic2.mq4: DBuffer[i] = iMAOnArray(KBuffer, 0, DPeriod, 0, MODE_SMA, i); experts/indicators/Phy__Stochastic2Convergence.mq4: KBuffer[i] = iMAOnArray(KFast, 0, SlowPeriod, 0, MODE_SMA, i); experts/indicators/Phy__Stochastic2Convergence.mq4: DBuffer[i] = iMAOnArray(KBuffer, 0, DPeriod, 0, MODE_SMA, i); experts/indicators/Phy__StraightMAForTicks.mq4: ma1[i]=iMAOnArray(tickArray, 0, period1, 0, ma_method1, i); experts/indicators/Phy__StraightMAForTicks.mq4: ma2[i]=iMAOnArray(tickArray, 0, period2, 0, ma_method2, i); experts/indicators/Phy__Up_Down_Multiples-Chart.mq4: bufferMA[i] = iMAOnArray( buffer, Bars, 13, 0, MODE_SMA, i); experts/indicators/Phy__Up_Down_Multiples-Chart.mq4: bufferMA1[i] = iMAOnArray( buffer, Bars, 34, 0, MODE_SMA, i); experts/indicators/Phy__Up_Down_Multiples.mq4: bufferMA[i] = iMAOnArray( buffer, Bars, 13, 0, MODE_SMA, i); experts/indicators/Phy__Up_Down_Multiples.mq4: bufferMA1[i] = iMAOnArray( buffer, Bars, 34, 0, MODE_SMA, i); experts/indicators/SMI.mq4: EMA_SM[i]=iMAOnArray(SM_Buffer,0,Period_R,0,MODE_EMA,i); experts/indicators/SMI.mq4: EMA_HQ[i]=iMAOnArray(HQ_Buffer,0,Period_R,0,MODE_EMA,i); experts/indicators/SMI.mq4: EMA2_SM[i]=iMAOnArray(EMA_SM,0,Period_S,0,MODE_EMA,i); experts/indicators/SMI.mq4: EMA2_HQ[i]=iMAOnArray(EMA_HQ,0,Period_S,0,MODE_EMA,i); experts/indicators/SMI.mq4: Signal_Buffer[i]=iMAOnArray(SMI_Buffer,0,Signal,0,MODE_EMA,i); experts/indicators/Stochastic.mq4: SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod,0,MODE_SMA,i); experts/indicators/Traders_Dynamic_Index.mq4: MaBuf[i] = (iMAOnArray(RSIBuf,0,RSI_Price_Line,0,RSI_Price_Type,i)); experts/indicators/Traders_Dynamic_Index.mq4: MbBuf[i] = (iMAOnArray(RSIBuf,0,Trade_Signal_Line,0,Trade_Signal_Type,i)); experts/scripts/Phy__Stochastic.mq4: SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod,0,MODE_SMA,i); |
|
MaxPayne
2007.11.05 02:36
phy wrote: Hi Phy,total -- not sure, would have to play with it to find out what it means shift -- the bar number for which the indicator returns the calculated value ma_shift -- moves the "result" of the calculation to a different bar. Open a chart, add Moving Average indicator. in properties, a negative shift moves the MA line to the left, a positive shift moves it to the right. ----- I too have needed to use two loops to get valid values when using arrays. you're right! The bars do get shifted with ma_shift. See the output. Well, I will try to put the code into an EA again. Feedback will come later. Cheers! Max |
|
DxdCn
2007.11.05 04:51
yes you can use it anywhere, but from my exp, should be sure and be care for buffer's size and content used for iMAOnArray |
|
DayTrader
2009.02.08 11:56
Be very carefull if you try to use iMAOnArray in an EA. I think it is meant to be used only in indicators. The problem is mainly the direction...it counts backwards... you'd have to use ArraySetAsSeries, but that only works in indicators. Actually ArraySetAsSerie does not affect the array you're pointing to... instead it acts on the linked indicator buffer, so its useless in an EA. This shit kept me down for days! I've had so much problems with it that I had to recode it into a custom function to get it to work properly. |
|
wmrazek
2010.01.17 23:46
DayTrader wrote >>
Be very carefull if you try to use iMAOnArray in an EA. I think it is meant to be used only in indicators. The problem is mainly the direction...it counts backwards... you'd have to use ArraySetAsSeries, but that only works in indicators. Actually ArraySetAsSerie does not affect the array you're pointing to... instead it acts on the linked indicator buffer, so its useless in an EA. This shit kept me down for days! I've had so much problems with it that I had to recode it into a custom function to get it to work properly. Hi! I have now spent one evening (and 2 beers, 1 coffe so far...) trying to understand iMAOnArray. I found this thread and I got a little scared to read how you all have struggled with this thing. Would you like to share your custom function? |