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

 

By the way, the analogue of Assert

#define  ASSERT (STD_CAssert(__LINE__,__FUNCTION__)).Assert

class STD_CAssert{
   string function;
   int line;
public:
   STD_CAssert(int _line,string _func):line(_line),function(_func){}
   void Assert(bool condition,string text=NULL);
  };
//--------------------------------------------------------------------------
void STD_CAssert::Assert(bool condition,string reason=NULL){
   if (condition) return;
   Alert(StringFormat("Assert in line %i, function %s.\nReason: %s.",line,function,reason==NULL||reason==""?"Unknow":reason));
   int a=0;
   int b=1/a;}

void OnStart()
{
   Test();
}

void Test(){
   ASSERT(2==3,"Some reason");
}
 
Igor Makanu:

i can't be sure i need it!

If developers had given exit / abort as standard, then it would be possible to correctly terminate data processing, if, for example, TF is not ready - OHLC data, it would also be useful for processing order sending to server... it would be convenient to interrupt the code at any place and exit before the next tick without endless return() to exit from OnTick()

Actually it's possible to implement a crutch, but usability is bad there, I won't even show it to you although it should work.
 

Although the usability seems to have been improved. In general, every function or method call with possible output, including nested functions, should be wrapped in _call macro. For those interested, feel free to write the rest for all handlers. It was written on a crank, as a test of an idea, so it was not tested, from the word - at all.

#ifdef _DEBUG
   #define  DELETE(dObj) do if (CheckPointer(dObj)!=POINTER_INVALID) {delete dObj; dObj=NULL;} while(false)
#else
   #define  DELETE(dObj) do {delete dObj; dObj=NULL;} while(false)
#endif

#define  START  class STD_CStart; void OnStart(){std_start=new STD_CStart; std_start.Main(); DELETE(std_start);}
#define  ON_START  START\
static STD_CStart* std_start=NULL;  \
class STD_CStart{   \
public: void Main();   \
};                \
void STD_CStart::Main

#define  DELETE_EVENTS do if (std_start!=NULL) DELETE(std_start); while(false)
#define  EXIT(out) do {DELETE_EVENTS; return out;} while(false)
#define  CHECK(out) do if (!std_start) EXIT(out); while(false)
#define _call(funk,out) do {funk;CHECK(out);} while(false)

ON_START()
{
   int x=0;
   Print("Start");
   _call(TestInt(4),);
   Print(++x);
   _call(TestInt(1),);
   Print(++x);
   _call(TestInt(6),);
   Print(++x);
   TestVoid();   
}

int TestInt(int a){
   static int x=0;
   Print("Func call ",++x);
   if (a<3) EXIT(NULL);
   return 0;
}

void TestVoid(){
   Print("Error");}
 

There is no protection in MT5 against accidental closure of the terminal. There was such a scenario recently.

  • The terminal and the browser are open to the whole window. I am in the browser.
  • Browser is frozen, I click on the cross in the right-upper corner.
  • It does not close, I press it a few more times.
  • At some point during pressing, browser closes - window disappears. And at this time the cross of the terminal under the cursor, where I pressed.
  • The terminal closes, so quickly that it is simply not noticeable. Especially when many Terminals are open.

This is a very unpleasant situation during e.g. Batch Optimisation. But it's even worse for the Battle Advisor. You may be stupid not to notice that you have killed your battle terminal.


You have put such a protection.

void OnDeinit( const int Reason )
{
  if (Reason == REASON_CLOSE)
    MessageBox("Terminal is being closed!");
}

When you close it, a message appears for five seconds. So you can figure out what really happened. It is strange that there is no protection in the Terminal.

 
fxsaber:

There is no protection in MT5 against accidental closure of the terminal. There was such a scenario recently.

  • The terminal and the browser are open to the whole window. I am in the browser.
  • Browser is frozen, I click on the cross in the right-upper corner.
  • It does not close, I press it a few more times.
  • At some point during pressing, browser closes - window disappears. And at this time the cross of the terminal under the cursor, where I pressed.
  • The terminal closes, so quickly that it is simply not noticeable. Especially when many Terminals are open.

This is a very unpleasant situation during e.g. Batch Optimisation. But it's even worse for the Battle Advisor. You may be stupid not to notice that you have killed your battle terminal.


You have put such a protection.

When you close it, a message appears for five seconds. So you can figure out what really happened. Strange that the Terminal doesn't have a protection.

There are a few simpler options.

  1. Keep the Combat Terminal minimised.
  2. Keep the battle terminal on the VPS
  3. Tie naughty hands and stay away from the computer. )))
  4. I'll have to think, maybe something will come up...)))
 
Alexey Viktorov:

There are a few simpler options.

  1. Keep the battle terminal minimised.
  2. Keep the battle terminal on a VPS
  3. Tie up your naughty hands and stay away from your computer. )))
  4. Gotta think, maybe something will come up...)))

On VPS may close too. I have experts there sending Push.

And it's really easy to hit the wrong cross when the wind interface slows down. I've done it, now I close it on taskbar in context menu.

 
Alexey Viktorov:

There are a few easier options.

Install a desktop manager and dedicate one desktop to the browser and stuff, and dedicate another desktop to the terminals.

Or install Linux (the desktop manager comes with it :) )

 
Vladimir Simakov:

By the way, the analogue of Assert

For any mql statement implementation, it makes sense to use DebugBreak function for debug mode. Makes life very easy when debugging and much more useful than just crashing out.
 

Forum on trading, automated trading systems and strategy testing

Libraries: MT4Orders

fxsaber, 2020.04.07 18:47

Partial execution is very easy to find in MT5.
// true - сделка в результате частичного исполнения.
bool IsPartial( const ulong TicketDeal )
{
  const ulong TicketOrder = HistoryDealGetInteger(TicketDeal, DEAL_ORDER);
  
  return((HistoryDealGetInteger(TicketDeal, DEAL_TYPE) <= DEAL_TYPE_SELL) &&
         (!TicketOrder ||
          (HistoryDealGetDouble(TicketDeal, DEAL_VOLUME) != HistoryOrderGetDouble(TicketOrder, ORDER_VOLUME_INITIAL))));
}
 

On a hedge a position can consist of several IN trades. This is done by partial execution.

In this case the order that is partially executed will change its ORDER_TIME_SETUP(_MSC) to the time of the first (possibly penultimate) trade. In other words, it would be impossible to determine from the history when, for example, BuyLimit was placed.


As a consequence, the position on the hedge can have a fractional opening price, as can often be seen on the netting.