Features of the mql5 language, subtleties and tricks - page 225

 

Another sudden MQL nuance - virtual methods are not called from constructors.

in code

class Manager;
class InfoPanel {
public:
   InfoPanel(Manager *m)    { manager=NULL; if (m!=NULL) m.Attach(&this); /* m.Attach в свою очередь должен дёрнуть виртуальный OnAttach (но не будет) */ };
   ~InfoPanel()   { };
   virtual void OnAttach(Manager *m) { PrintFormat("InfoPanel attach"); if (manager!=NULL) manager.Detach(&this); manager=m;};
   virtual void OnDetach(void) { PrintFormat("InfoPanel detach"); manager=NULL;};
   virtual void Draw(void) { PrintFormat("InfoPanel draw"); };
public:
   Manager *manager;
};
class HiLow: public InfoPanel {
public:
   HiLow(Manager *m):InfoPanel(m) { } ;
   ~HiLow() { };
   virtual void OnAttach(Manager *m) { PrintFormat("HiLow attach"); InfoPanel::OnAttach(m); };
   virtual void OnDetach(void) { PrintFormat("HiLow detach"); };
   virtual void Draw(void) { PrintFormat("HiLow draw"); };
};
class Manager {
public:
   Manager()  { };
   ~Manager() { };
   void Attach(InfoPanel *pan) {
      int id=ArraySize(panels);
      ArrayResize(panels,id+1);
      panels[id]=pan;
      panels[id].OnAttach(&this);
   }
/// some code
}
////
void OnStart()
{
   Manager *man=new Manager();
   HiLow *hilow=new HiLow(man);
   man.Draw();
   man.Detach(hilow);
   delete hilow;
   delete man;
}

you can't do it like this :-)) OnAttach of the parent class will be called from the constructor ; And during normal access - of the child class.


youcan't understand it, you have to memorise it:-)

 
Maxim Kuznetsov #:

Another sudden nuance of MQL - virtual methods are not called from constructors.

in the code


you can't do it like this :-)) OnAttach of the parent class will be called from the constructor ; And during normal access - of the child class.


youcan't understand it, you have to memorise it:-)

Why is it impossible to understand? Initialisation of a pointer to a method in the table of virtual methods takes place in the constructor. The constructor of the parent class is called first, then the constructor of the successor. Accordingly, when the body of the parent class constructor is executed, in the virtual methods table the pointer points to the address of the base class method.

PS. This is for the eternal cholivar about whether you should learn C++. If you study it, digging to the essence of things and not cramming, such things become self-evident).

 
Vladimir Simakov #:

Why is it impossible to understand? Initialisation of a pointer to a method in the table of virtual methods takes place in the constructor. The constructor of the parent class is called first, then the constructor of the successor. Accordingly, when the body of the parent class constructor is executed, the pointer points to the address of the base class method in the virtual methods table.

PS. This is for the eternal cholivar about whether you should learn C++. If you study it, digging to the essence of things and not cramming, such things become self-evident).

After scripts, where everything is possible, it is a bit surprising that "a constructor cannot be virtual" :-))

 
Maxim Kuznetsov #:

after scripts, where everything is possible, it is a bit surprising that "a constructor cannot be virtual" :-)

For your "trouble", there is such a solution: https: //habr.com/ru/post/64369/.

PS. Not exactly the same, of course, but as a general direction of thought

Виртуальный конструктор
Виртуальный конструктор
  • 2009.07.13
  • habr.com
Все мы знаем, что в C++ нет такого понятия как виртуальный конструктор , который бы собирал нужный нам объект в зависимости от каких-либо входных параметров на этапе выполнения. Обычно для этих целей используется параметризованный фабричный метод (Factory Method) . Однако мы можем сделать «ход конем» и сымитировать поведение виртуального...
 
Maxim Kuznetsov #:

after scripts, where everything is possible, it is a bit surprising that "a constructor cannot be virtual" :-)

unexpected?

Imagine if HiLow::OnAttach was called. If there were new fields in HiLow and OnAttach would read them, there would be "use of uninitialised variables" (because HiLow constructor has not started executing yet).

 

POSITION_TIME_UPDATE is relevant only in changing the lot of a position. For example, partial closing of a position on any type of account or a refill on netting.

Changes in SL/TP levels do not affect POSITION_TIME_UPDATE.

To paraphrase, POSITION_TIME_UPDATE is affected only by modifications reflected in the Trading History - trades. SL/TP-levels do not belong to such modifications, so they do not affect them.


Yes, indeed, it is so on a real account.

But after building the Expert Advisor, I try it in the tester, and it turns out that in the tester, modifications of SL/TP-levels affect POSITION_TIME_UPDATE.

Here is an excerpt from the logs.

Here I have highlighted the time of position opening in yellow, and then (on the next tick) in red the time of modifying (placing) SL and TP to it. Then I check the POSITION_TIME and POSITION_TIME_UPDATE times using the print -they are different.

LQ      0       11:54:55.049    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:00   CTrade::OrderSend: market buy 0.20 AUDCAD [done at 0.95325]
CL      0       11:54:55.049    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:00   FnPositionOpen: Тикет открытой сделки: 6; Тикет открытого ордера: 7
PD      0       11:54:55.049    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:00   Order #7  State: ORDER_STATE_FILLED
JN      0       11:54:55.063    Trade   2021.05.10 12:00:01   position modified [#7  buy 0.2 AUDCAD 0.95325 sl: 0.94901 tp: 0.96150]
PM      0       11:54:55.064    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:01   CTrade::OrderSend: modify position #7  AUDCAD (sl: 0.94901, tp: 0.96150) [done]
HP      0       11:54:55.064    Trade   2021.05.10 12:00:01   sell stop 0.2 AUDCAD at 0.94901 tp: 0.94492 (0.95319 / 0.95324 / 0.95319)
HN      0       11:54:55.065    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:01   CTrade::OrderSend: sell stop 0.20 AUDCAD at 0.94901 tp: 0.94492 [done]
GR      0       11:54:55.074    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.10 12:00:02   ================ 1620648000<1620648001

Where modification of SL and TP is within the same second, POSITION_TIME and POSITION_TIME_UPDATE times are of course the same.

RH      0       12:11:44.946    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   CTrade::OrderSend: market buy 0.20 AUDCAD [done at 0.95198]
NR      0       12:11:44.946    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   FnPositionOpen: Тикет открытой сделки: 5; Тикет открытого ордера: 5
HM      0       12:11:44.946    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   Order #5  State: ORDER_STATE_FILLED
KG      0       12:11:44.946    Trade   2021.05.07 16:00:00   position modified [#5  buy 0.2 AUDCAD 0.95198 sl: 0.94537 tp: 0.96496]
CJ      0       12:11:44.947    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   CTrade::OrderSend: modify position #5  AUDCAD (sl: 0.94537, tp: 0.96496) [done]
KK      0       12:11:44.956    Trade   2021.05.07 16:00:00   sell stop 0.2 AUDCAD at 0.94537 tp: 0.93890 (0.95195 / 0.95199 / 0.95195)
OE      0       12:11:44.957    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   CTrade::OrderSend: sell stop 0.20 AUDCAD at 0.94537 tp: 0.93890 [done]
RK      0       12:11:44.957    eMAEnvelopeTrade (AUDCAD,M30)   2021.05.07 16:00:00   ================ 1620403200<1620403200
 
Andrey Kaunov #:
in the tester, changes in SL/TP levels affect POSITION_TIME_UPDATE

Thanks for the information!

 
fxsaber #:

The ORDER_TIME_SETUP_MSC field changes when orders are partially executed.

As a consequence, DEAL_TIME_MSC can be less than ORDER_TIME_SETUP_MSC of its order.

Example.


 
Could you please tell me how to compile all the files in the directory?
 
Aleksey Vyazmikin #:
Could you please tell me how to compile all files in a directory?
In the navigator, right click on the directory -> "Compile"