- What is the equivalent of iMAOnArray on MQL5
- Wishes for MT5
- Issue: Moving Average applied on a Custom Indicator
The third buffer - emabands - isn't showing the correct data - doesn't matter if you switch the bands buffer from UPPER to LOWER. So what could I be missing here?
//+------------------------------------------------------------------+ //| test.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 3 #property indicator_color1 C'255, 0, 0' #property indicator_color2 C'0, 255, 0' #property indicator_color3 C'0, 0, 255' double ema[],bands[],emabands[]; int ema_handle, bands_handle, emabands_handle; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ema); PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); SetIndexBuffer(1,bands); PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE); SetIndexBuffer(2,emabands); PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_LINE); ema_handle = iMA(_Symbol, PERIOD_CURRENT, 15, 0, MODE_EMA, PRICE_CLOSE); bands_handle = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2, ema_handle); emabands_handle = iMA(_Symbol, PERIOD_CURRENT, 5, 0, MODE_EMA, bands_handle); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- int limit=rates_total-prev_calculated; //--- if(rates_total<=10) return(0); //--- if(prev_calculated>0) limit++; ArraySetAsSeries(ema, true); ArraySetAsSeries(bands, true); ArraySetAsSeries(emabands, true); if(!FillArraysFromBuffers(ema, 0, ema_handle, limit)) return(0); if(!FillArraysFromBuffers(bands, UPPER_BAND, bands_handle, limit)) return(0); if(!FillArraysFromBuffers(emabands, 0, emabands_handle, limit)) return(0); //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ bool FillArraysFromBuffers(double &buffer[], int buf, int handle, int amount ) { if(CopyBuffer(handle,buf,0,amount,buffer)<0)return(false); return(true); }
Alright so here is a simple representation of what I mean.
The third buffer - emabands - isn't showing the correct data - doesn't matter if you switch the bands buffer from UPPER to LOWER. So what could I be missing here?
First of all-
if(rates_total<=10) return(0);
Seems very arbitrary, as the number 10 doesn't correlate with any of your EA.
Because each EA is of the previous one, you need to 'accumulate' all of their periods.
(It is very late, so my math may be a bit off, but I hope you'll get my point)
In your example, these are the periods of the EAs-
ema - 15
bands - 20
emabands - 5
So, for calculating the first value of ema we need 15 bars
Then, to calculate the first value of bands we need 20 values of ema, meaning the initial 15 bars ema needed for first calculation + another 19 more bars for the other 19 values of ema (so a total of 34),
Then, to calculate the first value of emabands we need 5 values of bands, meaning the 34 bars needed to calculate the first value of bands + another 4 bars for the other 4 values of bands (so a total of 38 bars).
Again, due to the hour my math may be a bit off, but you need at least 38 bars for a proper calculation of all 3 MAs (as opposed to the arbitrary 10 you've chosen).
I don't believe this causes any issues in your code above,
But it does worth mentioning...
Can you please give an example to what 'weird results' are you getting?
To see what I'm talking about, you can switch the bands buffer from upper to lower - and you will see the buffer changes - but the emabands doesn't - althouth it should be adjusting to the array coming from bands - but untouched.
if(!FillArraysFromBuffers(ema, 0, ema_handle, limit)) return(0); //if(!FillArraysFromBuffers(bands, UPPER_BAND, bands_handle, limit)) return(0); if(!FillArraysFromBuffers(bands, LOWER_BAND, bands_handle, limit)) return(0); if(!FillArraysFromBuffers(emabands, 0, emabands_handle, limit)) return(0);
Something as basic as this in MQL4:
ema[i] = iMA(_Symbol,_Period,15, 0, MODE_EMA, PRICE_CLOSE, i); band_up[i] = iBandsOnArray(ema, 0, 20, 2, 0, MODE_UPPER, i); ema_band[i] = iBandsOnArray(band_up, 0, 20, 2, 0, MODE_UPPER, i);
seems to be really tricky in MQL5:
ema_handle = iMA(_Symbol, PERIOD_CURRENT, 15, 0, MODE_EMA, PRICE_CLOSE); bands_handle = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2, ema_handle); emabands_handle = iBands(_Symbol, PERIOD_CURRENT, 20, 0, 2, bands_handle);
But this just doesn't work as expected.
Still need help if anybody has any idea.
Edit:
The handles themselves work fine - the ema_bands handle is using the bands_handle - it's just that it seems to be using the middle line as source - where I want it to be calculated on the Upper or Lower line, not the middle one.
https://www.mql5.com/en/forum/160#edit_form
or
https://www.mql5.com/en/forum/216114/page2
but there was never an answer.
Is really MQL5 that crippled?
- 2009.12.18
- www.mql5.com
Although I still find this fishy, it should be done easier than that.
Ok so self-five(!) and back to work.
Kudos for solving it on your own mate!
Yes, when passing indicator's handle to another indicator, it will always use buffer 0, regardless of your setting of the handle.
Just for you to know, for next time, you can import MovingAverages.mqh and use OnArray functions of moving averages.
Kudos for solving it on your own mate!
Yes, when passing indicator's handle to another indicator, it will always use buffer 0, regardless of your setting of the handle.
Just for you to know, for next time, you can import MovingAverages.mqh and use OnArray functions of moving averages.
So only thing left was recreating calculations using only buffers and arrays and voila - got the effect wanted.
Although I still find this fishy, it should be done easier than that.
Ok so self-five(!) and back to work.
Would you put example of your solution here?
I'm also facing similar problem and didn't understand very well what calculations you made there.
-
“Doesn't work” is meaningless — just like saying the car doesn't work. Doesn't start, won't go in gear, no electrical, missing the key, flat tires — meaningless.
How To Ask Questions The Smart Way. (2004)
When asking about code
Be precise and informative about your problem -
They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
How to call indicators in MQL5 - MQL5 Articles (2010)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use