Download MetaTrader 5

How to send internal events from one chart to another?

To add comments, please log in or register
Publish your programs in the Market. Make money with your knowledge!
yohmm
28
yohmm 2014.08.08 20:20 
Hello, I want to send internal events like CHARTEVENT_CLICK, CHARTEVENT_MOUSE_MOVE etc. from all open charts to one chart. Only this one chart has an EA attached which receives and processes the events.
The reason is: There is one panel on each chart. When I click/change one panel I want to auto update all other panels to keep them in sync.

For the panel I am using the CAppDialog class from the Standard Library. It handles events like this (in MyExpert.mq5):

void OnChartEvent(const int     id,
                  const long&   lparam,
                  const double& dparam,
                  const string& sparam
                 )
  {
   CControlsDialog *panel;
   panel=MyExpert.Panel(0); // example: get the panel that is on chart with index 0
   panel.ChartEvent(id,lparam,dparam,sparam);
  }
That works fine for the panel that is on the same chart as the EA. To make it work for a panel that isn’t on the same chart, the EA needs to listen to events on the other charts as well.

The Indicator “Spy Control panel MCM” seems to be a good solution. I added this to the code of the indicator:

void OnChartEvent(const int     id,
                  const long&   lparam,
                  const double& dparam,
                  const string& sparam)
  {
   //if(id>CHARTEVENT_CUSTOM)
   //   return;
   EventIntern(id,lparam,dparam,sparam);
   return;
  }

And this:

bool EventIntern(int id,
                long lparam,
              double dparam,
              string sparam)
  {
   int eventID=Chart_Index*1000+1000+id;
   if(EventChartCustom(Chart_ID,eventID,lparam,dparam,sparam))
      return(true);
   return(false);
  }
Chart_Index and Chart_ID are input parameters that are filled by the EA. Chart_Index is the index of the chart the indicator is attached to, Chart_ID is always the id of the chart the EA is attached to.
The Spy is now supposed to forward not only the events it was made for (NewBar and NewTick), but all internal events as well. And that works.
At least one problem remains: In the EA I need to know where the event came from AND if it is a custom event or an internal event. I can’t use lparam, dparam or sparam of OnChartEvent() event handler function (in MyExpert.mq5) for this because they are reserved for values like mouse positions, name of the element that was clicked etc. So I used the first parameter. The value of this parameter is a combination of two variables that are set in the Spy. One is the chart index (where did the event came from?) and the other is the event id (Is it an internal event?).
Let me explain it, I hope that makes it clear:
Custom events (NewBar, NewTick) come with an ID of 1000,1001,1002,...,1999 => chart index is in the last digits, event ID comes in lparam of OnChartEvent.
Internal events (Click, Mousemove etc.) come with an ID of 2000,2001,2002,…,2999,3000,…,4000,… => chart index is in the first digit, event id is in the last digits.
I know it seems a bit complicated, but I couldn’t find another solution. At least I now know where the event came from and I can distinguish between custom and internal events that were sent from the Spy.

See how it works in the updated OnChartEvent in MyExpert.mq5:

void OnChartEvent(const int     id,
                  const long&   lparam,
                  const double& dparam,
                  const string& sparam
                 )
  {
   int chart_event=id-CHARTEVENT_CUSTOM; // chart index or combination of chart index and event id
   
   //Print("OUT->id: ",id,"id: ",EnumToString((ENUM_CHART_EVENT)id),"lparam: ",lparam,"dparam: ",dparam,"sparam: ",sparam);
   
//--- Internal events send from Spy Agent indicator
   if(chart_event>=1000)
     {
      int i=0,chart_index=0,event_id=0,ce=chart_event;
      //--- get chart index and event ID of internal event      
      while(ce>1000)
        {
         ce=ce-1000;
         if(ce<1000)
           {
            event_id=chart_event-(i*1000)-1000;
            break;
           }
         i++;
        }
      chart_index=i;
      CControlsDialog *panel;
      panel=MyExpert.Panel(chart_index); // get panel on chart n
      panel.ChartEvent(event_id,lparam,dparam,sparam);
     }   
//--- Custom chart events from Spy
   else 
     {
      int chart_index=id-CHARTEVENT_CUSTOM;
      ENUM_CHART_EVENT_SYMBOL event=(ENUM_CHART_EVENT_SYMBOL)lparam;
      //--- Init
      if(event==CHARTEVENT_NEWBAR_NO)
        {
         MyExpert.OnSpyInit();
        }
      //--- New Bar
      if(event==CHARTEVENT_NEWBAR_M5)
        {
         MyExpert.OnNewBar();
        }
      //--- Tick
      if(event==CHARTEVENT_TICK)
        {
         MyExpert.OnTick();
        }
     }
  }

So far so good. However, the panel doesn’t work yet. There seems to be one (or more) event that the panel event handler needs to work properly and that isn’t forwarded by the Spy Indicator. I debugged Spy.mq5 and MyExpert.mq5, printed out all parameters and compared them, but I can’t find what’s wrong. That is so frustrating! So either I am missing one little thing or the approach to this problem is completely wrong and can be done with less complexity. Maybe there is an OnOtherChartEvent handler function that I haven’t seen?! :-)

Can you help me please? How can I forward all events from all open charts to my EA? Is there a way that is more convenient and easier? What do I have to do to make the panel work?
Any help is greatly appreciated…
To add comments, please log in or register