ISsue with Creating an indicator buffer that stores values for different timeframe (than the chart) and should be accessed by EA

 

Hi,

 I was creating an indicator that  has 2 buffers. 

double x_1hr[] , x_30min[];


This indicator has to be used on 4 hr chart (for convenience purpose). But it needs to also populate values in the x_1hr and x_30min buffer array after some calculation in the onCalculate function. The value in these arrays (x_1hr/x_30min) are then to be used by an EA that uses this indicator.

I tried to register these array as buffer by:

SetIndexBuffer(0, x_1hr, INDICATOR_DATA);
SetIndexBuffer(1, x_30min, INDICATOR_DATA);

But...

I noticed that the size of these buffer arrays is equal to the number of bars in chart (4 hr) that i apply the indicator on. 
However i need the  size of these buffer arrays to be the number of bars in 1 hr chart and 30 min chart respectively so that they can store values corresponding to those bars .
And i need these 2 arrays to be indicator buffer arrays because the values for these  will be used by a different EA (according to my understanding EA can only access indicator data buffer arrays). This EA will also be running on a 4 hr chart.

How can this be done?

Documentation on MQL5: Timeseries and Indicators Access / Bars
Documentation on MQL5: Timeseries and Indicators Access / Bars
  • www.mql5.com
Bars - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Varun Maithani: This indicator has to be used on 4 hr chart (for convenience purpose). But it needs to also populate values in the x_1hr and x_30min buffer array a

How do you expect to show multiple values (H1 or M30) on one (H4) bar?

 
William Roeder #:

How do you expect to show multiple values (H1 or M30) on one (H4) bar?

I don't intend to display those values. Those values are specifically for EA to utilise for trading purposes as well for alerting me when specific conditions are met (incase i only use the indicator) None of these buffers will be used for displaying anything so that is why i need them to be independent of the chart timeframe. 
 
Varun Maithani #: I don't intend to display those values. Those values are specifically for EA to utilise for trading purposes as well for alerting me when specific conditions are met (incase i only use the indicator) None of these buffers will be used for displaying anything so that is why i need them to be independent of the chart timeframe. 

Then simply have the EA call the indicator with the correct time-frame. Don't put all the different time-frames into one indicator.

The OnCalculate() event handler for indicators is designed to handle only one time-frame, the one on the chart or the one selected by the parameter of the calling iCustom() function.

So design and code your indicator an EA accordingly. Trying to fit a square block into a round hole is not going to work. Use the tools the way they were designed and meant to be used.

Alternatively, if your "indicator" is only for the EA and for no other purpose, then you can carry out all of the calculations in the EA itself without using an indicator. There will not be an OnCalculate() event handler, so you can handle and structure the data which ever way you choose.

 
Fernando Carreiro #:

Then simply have the EA call the indicator with the correct time-frame. Don't put all the different time-frames into one indicator.

The OnCalculate() event handler for indicators is designed to handle the time-frame of the chart or of the calling iCustom() function.

So design and code your indicator an EA accordingly. Trying to fit a square block into a round hole is not going to work.

Use the tools the way they were designed and meant to be used.

Alternatively, if your "indicator" is only for the EA and for no other purpose, then you can carry out all of the calculations in the EA itself without using an indicator. There will not be an OnCalculate() event handler, so you can handle and structure the data which ever way you choose.

I guess if there is no alternative to achieve the above needed way, i will try to explore refactoring the code into an EA.

I did have an idea, i wanted to ask about though, which may avoid the refactoring of the complicated already working logic of indicator. 

If I add values into the two above mentioned indicator array buffers, after every onCalculate function call(every tick) wheever the required conditions are satisfied, and then let the EA use the indicator (single instance) to fetch that value from the buffers, and place the trade if needed ( the value in buffer is no longer needed after the EA has seen it once), and then the indicator clears the buffer array values on next onCalculate call with 0s (not caring about size of buffer), 
then is there any downside to using the buffer like this to share the value with the EA? 

I would just pretend the buffer is an array and ignore any association with timeframe or time they represent. 

Do you think there is any downside to using it like this? 
Refactoring the indicator code into an EA or seperating the complicated logic already designed ( which has dependencies among different time frames and is already working as intended)  would take a lot of time and effort. 

Any opinions on this mentioned workaround?
Does the terminal apart from increasing the buffer array size by 1 every 4 hour, affect the indicator buffer in any other way? 

The updates to values in indicator buffer on every oncalculate call are accessible to the EA on every onTick call right? 
 
Varun Maithani #: I guess if there is no alternative to achieve the above needed way, i will try to explore refactoring the code into an EA. I did have an idea, i wanted to ask about though, which may avoid the refactoring of the complicated already working logic of indicator. If I add values into the two above mentioned indicator array buffers, after every onCalculate function call(every tick) wheever the required conditions are satisfied, and then let the EA use the indicator (single instance) to fetch that value from the buffers, and place the trade if needed ( the value in buffer is no longer needed after the EA has seen it once), and then the indicator clears the buffer array values on next onCalculate call with 0s (not caring about size of buffer), then is there any downside to using the buffer like this to share the value with the EA? I would just pretend the buffer is an array and ignore any association with timeframe or time they represent.Do you think there is any downside to using it like this? Refactoring the indicator code into an EA or seperating the complicated logic already designed ( which has dependencies among different time frames and is already working as intended)  would take a lot of time and effort. Any opinions on this mentioned workaround? Does the terminal apart from increasing the buffer array size by 1 every 4 hour, affect the indicator buffer in any other way? The updates to values in indicator buffer on every oncalculate call are accessible to the EA on every onTick call right? 

My intuition says that you are overcomplicating something simple. Why do you want 2 o 3 different time-frames in the same indicator when the EA can already call indicators of different time-frames?

For example if you need an RSI of the 30 min, 1 hour, and 4 hour, simple have the EA instantiate the iRSI three times, one for each time-frame. Each indicator handle will be for each time-frame. It is as simple as that.

If the example I have given does not fit your need, then please explain your logic behind the multi-time-frame in your indicator and we will offer you advice on how to achieve it.

 

Update:

Brief Background: 

My indicator has various buffers which are supposed to store occurrence of events(when certain conditions become true in different timeframes, one buffer for each timeframe in which I expect event to occur).  What i was looking for, was a way to use these buffers in an EA for it to automatically place trades immediately on detecting the necessary value in the previously mentioned indicator buffers.

The "perceived obstable" was that the buffers would have number of bars equal to the bars available in the timeframe fed as parameter into the handle of the indicator.

// eg of decleration of the indicator within the EA
custom_indicator_handle=iCustom(_Symbol,Timeframe,"Examples\\indicatorName",
                     input1,
                     input2,
                     input3
                     );

Idea

What I realised upon further thinking and the idea that I thought of was that:

I could initialize the indicator event buffers with 0 initially using ArrayInitialize.

Afterwards, I could simply store a value  within these buffers when the appropriate conditions were detected within my indicator logic .

The EA can immediately detect the value from the buffer and use it as cue to place the trade. 

I realised that the number of bars in the buffer did not really matter since all i needed was one value that would be placed in the buffer (the value basically indicated that EA can place the trade now).


Challenges

On attempting to implement this idea, i bumped into a few challenges where i had to really slam my head against the wall many times in frustration. I managed to solve these challenges but wanted to share here for possible other people who may encounter them. 

I am not sure if the documentation actually mention these requirements whether they are compulsary or have to be fulfilled in a certain way, for properly working buffers within an indicator.

Initially my indicator had just these 3 lines at top . x denoting number of buffers. Since I was not using the buffers to plot anything so i had put the indicator plots = 0. I had no idea if that ( indicator plots = 0 ) was a valid thing to do since my indicator was working perfectly on its own (it was primarily made to alert me ).

#property indicator_chart_window
#property indicator_buffers x
#property indicator_plots  0

However, when i tried to get the buffer values within the EA , i could not.

void OnTick()
  {

 int x_30_count = CopyBuffer(indicatorNameHandle, x_30_index,1 ,10, x_30_buffer);
 int x_1hr_count = CopyBuffer(indicatorNameHandle, x_1hr_index, 1, 30, x_1hr_buffer);
 Print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    x_30_count = ", x_30_count , "$$$$$$$$$$$     x_1hr_count = ", x_1hr_count );

}

 It kept printing x_30_count and x_1hr_count as -1. And I had no idea why. Initially i thought this issue is related to timeframe perhaps somehow.


Solution

But finally after many hit and trial attempts of changing various things in my indicator i learnt that Its

because of this line:

#property indicator_plots  0


When i changed it from 0 to number of buffers i had in indicator. The EA started fetching the buffer values properly. Inspite of that property I am not really using any buffer value to display anything on the chart so I find it an odd requirement.

I could not find such a requirement in the MQL5 reference (which pops up when i press F1 on highlighting a keyword in MetaEditor). I wonder if you guys know where more detailed documentation is present or do we just learn through hit and trial?

Finally i can start developing the rest of the EA logic. 

Thank you for your assistance @Fernando and  @William.