Send custom event from EA to indicator

 

I have coded an EA that starts a custom indicator...

int handle = iCustom(symbol, PERIOD_M1, "MyIndicator");

My indicator sends custom messages to the EA, and this all works as expected.

I have also added OnChartEvent() inside the indicator...

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
   if (id >= CHARTEVENT_CUSTOM)
   {
        ...
   }
}

...to enable me to receive custom events sent from the EA to the indicator. However, as the indicator was started by the EA, and they both run in the same chart, they both have the same chart ID. So when I run the following from the EA's code...

EventChartCustom(ChartID(), MY_CUSTOM_EVENT, 0, 0, _Symbol);

The only OnChartEvent() that appears to be able to receive the custom events is the event handler running in the EA.

Is it possible to send custom events from the EA and receive them in the indicators OnChartEvent()?

 

Just came across the following link, https://www.mql5.com/en/forum/36119 where Alain Verleyen states "That's expected behaviour, an indicator launched with iCustom is not running on a chart and don't react to chart events. Use ChartIndicatorAdd() to have it on the chart."

That sounds like it might also be true for custom chart events as well. If that is the case then what are solutions are there as using ChartIndicatorAdd() is not an option for me, because the new indicator that I create might not use the same symbol?

Chart Event not working when the indicator using Chart Event is called from EA using iCustom function
Chart Event not working when the indicator using Chart Event is called from EA using iCustom function
  • 2014.09.11
  • www.mql5.com
Hello People In my recent project, I tried to call an indicator, which uses chart event and button objects, from EA using iCustom function...
 
metaRaider #: Just came across the following link, https://www.mql5.com/en/forum/36119 where Alain Verleyen states "That's expected behaviour, an indicator launched with iCustom is not running on a chart and don't react to chart events. Use ChartIndicatorAdd() to have it on the chart." That sounds like it might also be true for custom chart events as well. If that is the case then what are solutions are there as using ChartIndicatorAdd() is not an option for me, because the new indicator that I create might not use the same symbol?

Two possibilities come to mind:

  1. Send a custom event from the indicator to the EA, informing the EA of the ChartId on which the custom indicator is running, Then use that ChartId to send custom events to the custom indicator. However, I have never tried this and I don't know if it will work.
  2. Use Global Terminal Variables to pass data between them. You will however have to poll the data instead of reacting to events.
 
Fernando Carreiro #:

Two possibilities come to mind:

  1. Send a custom event from the indicator to the EA, informing the EA of the ChartId on which the custom indicator is running, Then use that ChartId to send custom events to the custom indicator. However, I have never tried this and I don't know if it will work.
  2. Use Global Terminal Variables to pass data between them. You will however have to poll the data instead of reacting to events.

Hi Fernando,

I looked into the chart ID option, but as mentioned, the EA is running in a chart and the Indicator is started by the EA, so they both have the same chart ID.

I'm trying to avoid global variables, but I may not have a choice :-(

The only way I can currently see to fix this would be to create a new chart for each indicator (to make sure the symbol matched) and then attach the indicator to the newly created chart. Then (as you say) send the chart ID via an event back to the main controlling EA. But this would mean creating lots of charts I don't currently need, and wasting a lot of resources in the process.

 
metaRaider #: I looked into the chart ID option, but as mentioned, the EA is running in a chart and the Indicator is started by the EA, so they both have the same chart ID. I'm trying to avoid global variables, but I may not have a choice :-( The only way I can currently see to fix this would be to create a new chart for each indicator (to make sure the symbol matched) and then attach the indicator to the newly created chart. Then (as you say) send the chart ID via an event back to the main controlling EA. But this would mean creating lots of charts I don't currently need, and wasting a lot of resources in the process.

I have no ideia what you are trying to achieve, so all I can say is maybe try to rethink the logic of it all. Given that the Indicators are "hidden" and have no interaction with the user, why not try carry out the processing in the EA itself and not rely on having to send data to the custom indicator.

 
Fernando Carreiro #:

I have no ideia what you are trying to achieve, so all I can say is maybe try to rethink the logic of it all. Given that the Indicators are "hidden" and have no interaction with the user, why not try carry out the processing in the EA itself and not rely on having to send data to the custom indicator.

It took me long enough to think of this...ha ha!

So without boring you with too much detail, this is a summary...

EA runs and create multiples indicators (listeners).

The listeners (in an idle state) feed certain information back to the EA.

When the EA sees a certain situation, the EA (the bit I'm stuck on) needs to send a message to the particular indicator to change it's logic.

The listener (non-idle state) feeds different information back to the EA.


I could move a lot of the logic, but the problem is still telling the listeners what they should be doing.

 
metaRaider #: It took me long enough to think of this...ha ha! So without boring you with too much detail, this is a summary... EA runs and create multiples indicators (listeners). The listeners (in an idle state) feed certain information back to the EA. When the EA sees a certain situation, the EA (the bit I'm stuck on) needs to send a message to the particular indicator to change it's logic. The listener (non-idle state) feeds different information back to the EA. I could move a lot of the logic, but the problem is still telling the listeners what they should be doing.

The only thing the EA can’t do itself is detect tick events on other symbols besides the current chart symbol (OnTick event handler). That is the only thing that would require a “listener” custom indicator to do via a custom event.

Everything else, the EA can do itself without requiring indicator “listeners”. You can easily create logic in the EA to achieve the same thing as the “listeners”, as an EA can access OHLC and tick data for any and all symbols as well as detect new bars to trigger calculation updates. The only thing that it requires the “listener” custom indicators is for the new tick events on different symbols.

So, if your reduce your “listeners” to ONLY detecting new tick events for other symbols and nothing else, you can do the rest in the EA. If you need to compartmentalise your code, you can use OOP (classes, etc.).

 
Fernando Carreiro #:

The only thing the EA can’t do itself is detect tick events on other symbols besides the current chart symbol (OnTick event handler). That is the only thing that would require a “listener” custom indicator to do via a custom event.

Everything else, the EA can do itself without requiring indicator “listeners”. You can easily create logic in the EA to achieve the same thing as the “listeners”, as an EA can access OHLC and tick data for any and all symbols as well as detect new bars to trigger calculation updates. The only thing that it requires the “listener” custom indicators is for the new tick events on different symbols.

So, if your reduce you “listeners” to ONLY detecting new tick events for other symbols and nothing else, you can do the rest in the EA. If you need to compartmentalise your code, you can use OOP (classes, etc.).

OK, just been for a long walk...that usually helps :-) During the walk, I think I had a great idea, so just need to test my theory out to see if it works. It it doesn't then I will have to move most of the code to the EA, which I was in the process of speccing up, just in case.

I'm already using OOP so I have that covered, but thanks for the suggestion.

I was trying to reduce the burden on the EA doing too much of the heavy lifting, hence why some of the code was on the listening side (am I correct in thinking that EA's and indicators each get a thread if available - sorry, I haven't looked too much into this side yet).

Thanks again for your help, it's always good to liaise with other coders.

 
metaRaider #: OK, just been for a long walk...that usually helps :-) During the walk, I think I had a great idea, so just need to test my theory out to see if it works. It it doesn't then I will have to move most of the code to the EA, which I was in the process of speccing up, just in case. I'm already using OOP so I have that covered, but thanks for the suggestion. I was trying to reduce the burden on the EA doing too much of the heavy lifting, hence why some of the code was on the listening side (am I correct in thinking that EA's and indicators each get a thread if available - sorry, I haven't looked too much into this side yet). Thanks again for your help, it's always good to liaise with other coders.

Program Running

Program

Running

Note

Service

A separate thread, the number of threads for services is equal to the number of services

A looped service cannot break running of other programs

Script

A separate thread, the number of threads for scripts is equal to the number of scripts

A looped script cannot break running of other programs

Expert Advisor

A separate thread, the number of threads for Expert Advisors is equal to the number of Expert Advisors

A looped Expert Advisor cannot break running of other programs

Indicator

One thread for all indicators on a symbol. The number of threads is equal to the number of symbols with indicators

An infinite loop in one indicator will stop all other indicators on this symbol


 
Fernando Carreiro #:

Program Running

Program

Running

Note

Service

A separate thread, the number of threads for services is equal to the number of services

A looped service cannot break running of other programs

Script

A separate thread, the number of threads for scripts is equal to the number of scripts

A looped script cannot break running of other programs

Expert Advisor

A separate thread, the number of threads for Expert Advisors is equal to the number of Expert Advisors

A looped Expert Advisor cannot break running of other programs

Indicator

One thread for all indicators on a symbol. The number of threads is equal to the number of symbols with indicators

An infinite loop in one indicator will stop all other indicators on this symbol


<embarrassed> thanks.

Reason: