Huge Bugs in Controls Classes and/or MQL5 with Metatrader 4?

 

Dear MQL5 developers,

at least I hope you guys read this.

I started to create a set of classes to develop a trading environment on a visual basis. Everything fine so far, until I found a very odd behaviour when using the control classes. First I thought I´ve overseen something, but then I found out, that there must be very huge bug in the classes, somewhere behind CWndContainer/CWnd. What I saw first was, that after resizing a CWndContainer object, it dropped added/bound elements. Just like that. Or when resizing a CWndClient object, the positions started to shift.

Then I tried something very simple, I took a sample from you which I found here, which creates a floating dialog window. That works, as it seems. BUT ... when I define just two instead of one class object, the whole thing goes crazy! When Im typing something into the edit fields and so on, the other window is affected. When I click on one listbox, the other reacts. Well, theses are classes and there is not static data in between. This behaviour is definitely buggy and the classes are not seriously usable.

Of course I´ve installed the newest version of Metatrader and tested it again. Same results. It´s not possible to create multiple instances of nested control objects. Now I don´t know if this is a problem of Metatrader or "just" a problem of the classes, which are kinda complex and are not so easy to debug. I´d be very unhappy if it would stay like that because it would mean, I cannot finish my work which costed me already plenty of time.

Looking forward to anybodies reply who can really help.


EDIT: In the meanwhile I found out, that this sample is originally a part of Metatrader 5. I´ve tried it with the same changes in Metatrader 5 and still got the same results. In my opinion there is something hardly wrong with the memory management, probably (hopefully!) within the MQL5 classes. But what confuses me most, is, that it seems that I am the first person who tries to develop seriously visual tools on a higher lever for Metatrader. Well, that´s were I started programming on Assembler Basis and C almost 25 years ago, it´s what I always could best :) But i really don´t want to write all the classes that I need for what I am planning. I expected that the control classes are ready to use, but they´re kinda beta.

//+------------------------------------------------------------------+
//|                                                     Controls.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include "ControlsDialog.mqh"
//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
CControlsDialog ExtDialog;
CControlsDialog ExtDialog2; // Second instance
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create application dialog
   if(!ExtDialog.Create(0,"Controls",0,20,20,360,324))
     return(INIT_FAILED);
   if(!ExtDialog2.Create(0,"Controls2",0,220,20,560,324))
     return(INIT_FAILED);   
//--- run application
   ExtDialog.Run();
   ExtDialog2.Run();
//--- succeed
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy dialog
   ExtDialog.Destroy(reason);
   ExtDialog2.Destroy(reason);
   
  }
//+------------------------------------------------------------------+
//| Expert chart event function                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // event ID  
                  const long& lparam,   // event parameter of the long type
                  const double& dparam, // event parameter of the double type
                  const string& sparam) // event parameter of the string type
  {
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
   ExtDialog2.ChartEvent(id,lparam,dparam,sparam);   
  }
//+------------------------------------------------------------------+
 
corresponding include file
//+------------------------------------------------------------------+
//|                                               ControlsDialog.mqh |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Edit.mqh>
#include <Controls\DatePicker.mqh>
#include <Controls\ListView.mqh>
#include <Controls\ComboBox.mqh>
#include <Controls\SpinEdit.mqh>
#include <Controls\RadioGroup.mqh>
#include <Controls\CheckGroup.mqh>
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT                         (11)      // indent from left (with allowance for border width)
#define INDENT_TOP                          (11)      // indent from top (with allowance for border width)
#define INDENT_RIGHT                        (11)      // indent from right (with allowance for border width)
#define INDENT_BOTTOM                       (11)      // indent from bottom (with allowance for border width)
#define CONTROLS_GAP_X                      (5)       // gap by X coordinate
#define CONTROLS_GAP_Y                      (5)       // gap by Y coordinate
//--- for buttons
#define BUTTON_WIDTH                        (100)     // size by X coordinate
#define BUTTON_HEIGHT                       (20)      // size by Y coordinate
//--- for the indication area
#define EDIT_HEIGHT                         (20)      // size by Y coordinate
//--- for group controls
#define GROUP_WIDTH                         (150)     // size by X coordinate
#define LIST_HEIGHT                         (179)     // size by Y coordinate
#define RADIO_HEIGHT                        (56)      // size by Y coordinate
#define CHECK_HEIGHT                        (93)      // size by Y coordinate
//+------------------------------------------------------------------+
//| Class CControlsDialog                                            |
//| Usage: main dialog of the Controls application                   |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
  {
private:
   CEdit             m_edit;                          // the display field object
   CButton           m_button1;                       // the button object
   CButton           m_button2;                       // the button object
   CButton           m_button3;                       // the fixed button object
   CSpinEdit         m_spin_edit;                     // the up-down object
   CDatePicker       m_date;                          // the datepicker object
   CListView         m_list_view;                     // the list object
   CComboBox         m_combo_box;                     // the dropdown list object
   CRadioGroup       m_radio_group;                   // the radio buttons group object
   CCheckGroup       m_check_group;                   // the check box group object

public:
                     CControlsDialog(void);
                    ~CControlsDialog(void);
   //--- create
   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
   //--- chart event handler
   virtual bool      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);

protected:
   //--- create dependent controls
   bool              CreateEdit(void);
   bool              CreateButton1(void);
   bool              CreateButton2(void);
   bool              CreateButton3(void);
   bool              CreateSpinEdit(void);
   bool              CreateDate(void);
   bool              CreateListView(void);
   bool              CreateComboBox(void);
   bool              CreateRadioGroup(void);
   bool              CreateCheckGroup(void);
   //--- handlers of the dependent controls events
   void              OnClickButton1(void);
   void              OnClickButton2(void);
   void              OnClickButton3(void);
   void              OnChangeSpinEdit(void);
   void              OnChangeDate(void);
   void              OnChangeListView(void);
   void              OnChangeComboBox(void);
   void              OnChangeRadioGroup(void);
   void              OnChangeCheckGroup(void);
  };
//+------------------------------------------------------------------+
//| Event Handling                                                   |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CControlsDialog)
   ON_EVENT(ON_CLICK,m_button1,OnClickButton1)
   ON_EVENT(ON_CLICK,m_button2,OnClickButton2)
   ON_EVENT(ON_CLICK,m_button3,OnClickButton3)
   ON_EVENT(ON_CHANGE,m_spin_edit,OnChangeSpinEdit)
   ON_EVENT(ON_CHANGE,m_date,OnChangeDate)
   ON_EVENT(ON_CHANGE,m_list_view,OnChangeListView)
   ON_EVENT(ON_CHANGE,m_combo_box,OnChangeComboBox)
   ON_EVENT(ON_CHANGE,m_radio_group,OnChangeRadioGroup)
   ON_EVENT(ON_CHANGE,m_check_group,OnChangeCheckGroup)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CControlsDialog::CControlsDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CControlsDialog::~CControlsDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Create                                                           |
//+------------------------------------------------------------------+
bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//--- create dependent controls
   if(!CreateEdit())
      return(false);
   if(!CreateButton1())
      return(false);
   if(!CreateButton2())
      return(false);
   if(!CreateButton3())
      return(false);
   if(!CreateSpinEdit())
      return(false);
   if(!CreateListView())
      return(false);
   if(!CreateDate())
      return(false);
   if(!CreateRadioGroup())
      return(false);
   if(!CreateCheckGroup())
      return(false);
   if(!CreateComboBox())
      return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the display field                                         |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateEdit(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP;
   int x2=ClientAreaWidth()-INDENT_RIGHT;
   int y2=y1+EDIT_HEIGHT;
//--- create
   if(!m_edit.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_edit.ReadOnly(true))
      return(false);
   if(!Add(m_edit))
      return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "Button1" button                                      |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton1(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+BUTTON_WIDTH;
   int y2=y1+BUTTON_HEIGHT;
//--- create
   if(!m_button1.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button1.Text("Button1"))
      return(false);
   if(!Add(m_button1))
      return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "Button2" button                                      |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton2(void)
  {
//--- coordinates
   int x1=INDENT_LEFT+(BUTTON_WIDTH+CONTROLS_GAP_X);
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+BUTTON_WIDTH;
   int y2=y1+BUTTON_HEIGHT;
//--- create
   if(!m_button2.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button2.Text("Button2"))
      return(false);
   if(!Add(m_button2))
      return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "Button3" fixed button                                |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton3(void)
  {
//--- coordinates
   int x1=INDENT_LEFT+2*(BUTTON_WIDTH+CONTROLS_GAP_X);
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+BUTTON_WIDTH;
   int y2=y1+BUTTON_HEIGHT;
//--- create
   if(!m_button3.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button3.Text("Locked"))
      return(false);
   if(!Add(m_button3))
      return(false);
   m_button3.Locking(true);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "SpinEdit" element                                    |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateSpinEdit(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- create
   if(!m_spin_edit.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_spin_edit))
      return(false);
   m_spin_edit.MinValue(10);
   m_spin_edit.MaxValue(1000);
   m_spin_edit.Value(100);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "DatePicker" element                                  |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateDate(void)
  {
//--- coordinates
   int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- create
   if(!m_date.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_date))
      return(false);
   m_date.Value(TimeCurrent());
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "ListView" element                                    |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateListView(void)
  {
//--- coordinates
   int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+2*CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+LIST_HEIGHT-CONTROLS_GAP_Y;
//--- create
   if(!m_list_view.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_list_view))
      return(false);
//--- fill out with strings
   for(int i=0;i<16;i++)
      if(!m_list_view.AddItem("Item "+IntegerToString(i)))
         return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "ComboBox" element                                    |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateComboBox(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- create
   if(!m_combo_box.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_combo_box))
      return(false);
//--- fill out with strings
   for(int i=0;i<16;i++)
      if(!m_combo_box.ItemAdd("Item "+IntegerToString(i)))
         return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "RadioGroup" element                                  |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateRadioGroup(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+RADIO_HEIGHT;
//--- create
   if(!m_radio_group.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_radio_group))
      return(false);
//--- fill out with strings
   for(int i=0;i<3;i++)
      if(!m_radio_group.AddItem("Item "+IntegerToString(i),1<<i))
         return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Create the "CheckGroup" element                                  |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateCheckGroup(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+
          (RADIO_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+GROUP_WIDTH;
   int y2=y1+CHECK_HEIGHT;
//--- create
   if(!m_check_group.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2))
      return(false);
   if(!Add(m_check_group))
      return(false);
//--- fill out with strings
   for(int i=0;i<5;i++)
      if(!m_check_group.AddItem("Item "+IntegerToString(i),1<<i))
         return(false);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton1(void)
  {
   m_edit.Text(__FUNCTION__);
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton2(void)
  {
   m_edit.Text(__FUNCTION__);
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton3(void)
  {
   if(m_button3.Pressed())
      m_edit.Text(__FUNCTION__+"On");
   else
      m_edit.Text(__FUNCTION__+"Off");
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeSpinEdit()
  {
   m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_spin_edit.Value()));
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeDate(void)
  {
   m_edit.Text(__FUNCTION__+" \""+TimeToString(m_date.Value(),TIME_DATE)+"\"");
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeListView(void)
  {
   m_edit.Text(__FUNCTION__+" \""+m_list_view.Select()+"\"");
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeComboBox(void)
  {
   m_edit.Text(__FUNCTION__+" \""+m_combo_box.Select()+"\"");
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeRadioGroup(void)
  {
   m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_radio_group.Value()));
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeCheckGroup(void)
  {
   m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_check_group.Value()));
  }
//+------------------------------------------------------------------+

//===============================================================================================================================

// GetID() - returns unique ID to pass to Create()    

//=============================================================================================================================== 

// Variable outside the class
static int __id_counter = 0; 

// Function inside the class
string GetID()
   {
      __id_counter++;
      Print(__id_counter); // Check it
      return ("#" + string(__id_counter));
      
   }
 
PS: Second time I read this, my text sounds a bit rude. Of course it is not meant like that. I am new to MT and I am still impressed of what is possible with the C++ interface and I am still convinced that I ve chosen the right platform to develop. And if I will get the support I need, I will develop tools for MT that the community will like. Promised :) I just don't want to reinvent the reel, thats it. 
 

Hello,

If you want to be read by Metaquotes developpers, you should write to ServiceDesk.

Get in touch with developers using Service Desk!
Get in touch with developers using Service Desk!
  • www.mql5.com
We therefore attach great importance to all user reports about issues in our programs and try to answer each one of them. - - Category: general
 
Didn´t know that. Thank you.
 

I am not sure if Service Desk has already replied to your issue, but I encountered a similar problem before.

The problem has something to do with the Run() function of CAppDialog. Each control (including CAppDialog) creates a unique ID for itself, based on the subwindow. This ID is then passed down to any other controls they contain, so that all controls within the dialog window will have a unique ID. However, in your case, you have two separate CAppDialog instances, and both instances do not know that the other exists. As a result, they create the basically the same IDs for each of their controls, despite the controls having different names. This explains why clicking on one control on one dialog window triggers the same event on the other.

One solution to the problem is this:

  1. Create a static class member that counts the number of instances of the class
  2. Replace/add the value of the static member to the only argument of the Id() function (under Run())
  3. Increment the static member

Here is a screen shot of the result:

https://www.mql5.com/en/charts/3823800/eurusd-h1-international-capital-markets

Chart EURUSD, H1, 2015.08.18 05:17 UTC, International Capital Markets Pty Ltd., MetaTrader 4, Real
Chart EURUSD, H1, 2015.08.18 05:17 UTC, International Capital Markets Pty Ltd., MetaTrader 4, Real
  • www.mql5.com
Symbol: EURUSD. Periodicity: H1. Broker: International Capital Markets Pty Ltd.. Trading Platform: MetaTrader 4. Trading Mode: Real. Date: 2015.08.18 05:17 UTC.
Files:
 

Hi Enrico,

thank you very much, this will help.

During my "investigations" I also figured out, that the processing of the ChartEvent is very ineffective, the reason for this is just the same: No instance managing, no saving of processing time is possible. This means, if you have several charts with several dialogues with several objects - each member of the dialog processes MOUSE_MOVE no matter if it can handle it or not - processes this. As a result, you will end up in performance problems. You see this already when you enter some text into an CEdit() an move the mouse, the input starts to flicker. 

 I think one can do better.  

 

For what it's worth, I'm also having a massive headache trying to do anything remotely complex with these controls.

It seems they work fine provided you create them once, and then don't want to do anything like dynamically removing or recreating them. As soon as you start doing this however, all sorts of weird behaviour starts cropping up, elements shifting position, invalid pointer exceptions getting thrown. And, as you mentioned, it's something of a nightmare to debug.

It's a shame, because these are potentially a huge time-saving set of standard controls which I could use for many applications, but they are indeed in a very "beta" state at present. 

 

Hello,

 Someone try to use the Enrico exemple and with the EA in the chart, change more than two times the TF?

Here was totally denconfigured! :(

 

Someone can help me? 

 
Enrico Lambino:

I am not sure if Service Desk has already replied to your issue, but I encountered a similar problem before.

The problem has something to do with the Run() function of CAppDialog. Each control (including CAppDialog) creates a unique ID for itself, based on the subwindow. This ID is then passed down to any other controls they contain, so that all controls within the dialog window will have a unique ID. However, in your case, you have two separate CAppDialog instances, and both instances do not know that the other exists. As a result, they create the basically the same IDs for each of their controls, despite the controls having different names. This explains why clicking on one control on one dialog window triggers the same event on the other.

One solution to the problem is this:

  1. Create a static class member that counts the number of instances of the class
  2. Replace/add the value of the static member to the only argument of the Id() function (under Run())
  3. Increment the static member

Here is a screen shot of the result:

https://www.mql5.com/en/charts/3823800/eurusd-h1-international-capital-markets

Enrico Thank you very much, I was a bit stuck with this issue regarding working with multiple panels, but I already have an idea of where to go.
regards!!