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

 
When calling a macro, you may not specify any parameter (omit it), sometimes you want to specifically allow a macro to work with an unspecified parameter.


For such cases, here are some auxiliary macros.

1. sometimes you want to determine inside your macro whether a parameter has been set or not. IS_PARAMETER_SET(p) defines an expression, which returns true if p is set (even if string variable ==NULL).

Attention: the expression is evaluated after preprocessing at compile time!!!, i.e. it cannot be used to implement something like #ifdef IS_PARAMETER_SET(p) #else (this also applies to other macros below)

2. If you need to explicitly convert a parameter value to a string, to avoid a compile-time error with an unspecified parameter, you can use __EVAL_STR(p). If p is not specified or explicitly defined with NULL literal, it returns "". Not applicable to arrays, structures and classes.

The explicit conversion of a parameter to a number is __EVAL_NON_STR(p). If p is not set, returns 0. Does not work when p is a string!

Code and examples of use:

//Expression returns true if macro's parameter is specified.
#define  IS_PARAMETER_SET(p) ("" != #p || __hlp_macro_func(p))
bool __hlp_macro_func(const string p = NULL) {return "" == p;}
template<typename T> bool __hlp_macro_func(T p)    {return true;}
template<typename T> bool __hlp_macro_func(T& p)   {return true;}
template<typename T> bool __hlp_macro_func(T& p[]) {return true;}


//Expression returns parameter p; if parameter is not specified returns NULL; if p is string returns p
//Error for arrays and objects
#define __EVAL(p) (""==#p?NULL:p+NULL)


//Explicit conversion to string. If parameter is not specified or is constant NULL returns ""
//Error for arrays and objects
#define __EVAL_STR(p) (""==#p || "NULL"==#p? "" :(string)(p+NULL))


//Explicit conversion to number. If parameter is not specified returns 0. Works incorrect if p is string!
//Error for arrays and objects
#define __EVAL_NON_STR(p) ("" == #p? 0 : p+0)


struct S1
  {   int               a; };
class C1
  { int               a; };

void OnStart()
  {
//---
   Print(IS_PARAMETER_SET());                //false
   Print(IS_PARAMETER_SET(""));              //true
   Print(IS_PARAMETER_SET("test"));          //true
   Print(IS_PARAMETER_SET(NULL));            //true
   Print(IS_PARAMETER_SET(0));               //true
   Print(IS_PARAMETER_SET(1));               //true
   string str;
   Print(IS_PARAMETER_SET(str));             //true

   int arr[1];
   Print(IS_PARAMETER_SET(arr));             //true
   S1 _struct;
   Print(IS_PARAMETER_SET(_struct));         //true
   C1 _class;
   Print(IS_PARAMETER_SET(_class));          //true

#define   MACRO1_(a,b)  (IS_PARAMETER_SET(b)?a:-a)
   Print(MACRO1_(1, 0));                     //1
   Print(MACRO1_(1,));                       //-1

#define   MACRO2_(a,b,c)  Print(a," = ",b + c)
#define   MACRO3_(a,b,c)  Print(__EVAL_STR(a)," = ",__EVAL_NON_STR(b) + __EVAL_NON_STR(c))

 //MACRO2_(, 2,);                            // ',' - syntax error, parameter missed
   MACRO3_(, 2,);                            // = 2
   MACRO3_("a", 2, 3);                       // a = 5
  }


 
fxsaber:

The following code on theRannForex-Server demo account can immediately reproduce this situation by running this advisor.


Result.


By the way, the script shows (not always the first time) a bug in the synchronous OrderSend execution.

After OrderSend is executed for a few tens/hundreds of milliseconds, the order price is the old one, and not the one that was successfully placed by OrderSend.


Coming back to the topic of identical tickets, we can draw some conclusions.

  1. If a partial limit order is hanging, the tab "Orders and trades" will not show the generated trade.
  2. On a hedge, a single order can spawn multiple IN trades with different prices. The result will be a fractional (relative to pips) opening price of the position.
  3. You can close the generated position without removing the Partial Put. But if after that the pending order is triggered, then a trade will be opened with the ticket, equal to the ticket of the position, which was closed before. That is, there may be a situation where you close a position with a certain ticket. And then a position reappears with the same ticker.
  4. Partial execution may be implemented differently, depending on the broker's software. The above is a standard MT5 implementation.

If someone has managed to reproduce it on another trading server, please share the name.

Search string: Oshibka 010.

Back to the question of partial execution again.

1. Please clarify on point 3: "You may close the position you have formed without removing the Partial Execution. But if after that the order is triggered, a trade will open with a ticket equal to the ticket of the position you closed before. That is, there may be a situation where you close a position with a certain ticket. And then a position appears again with the same ticket."
In this case, was POSITION_IDENTIFIER equal to POSITION_TICKET or not?

2. Earlier in the "POSITION_TICKET != POSITION_IDENTIFIER" thread you demonstrated a different MT5 logic.

https://www.mql5.com/ru/forum/227423/page2#comment_6543129

fxsaber:

Conclusions

If we assume that this is normal behavior of MT5, and not a peculiarity of the broker's hack, then

  • ORDER_STATE_PARTIAL does not exist in historical orders.
  • Orders that are executed always have the ORDER_STATE_FILLED status.
  • When an order is partially executed, a corresponding new market order is created by the trade server (ORDER_REASON_CLIENT - even if the initial order is placed automatically (EXPERT)).
  • The old live order (the ticket is not changed) remains pending with a reduced volume (ORDER_VOLUME_CURRENT).
  • The old live order in this case gets the status ORDER_STATE_PARTIAL. Actually, this flag is the result of the comparison of ORDER_VOLUME_CURRENT and ORDER_VOLUME_INITIAL.
  • All open positions receive ID == OrderTicket. Where OrderTicket is the ticket generated by the trade server.
  • A trade always has exactly one historical order and its status is ORDER_STATE_FILLED.
  • Each executed historical order has exactly one trade.
  • The ORDER_VOLUME_INITIAL of any executed order is equal to the volume it was executed for. I.e. even the initial order that was canceled has an ORDER_VOLUME_INITITAL that is equal to the volume of the trade it spawned.
  • The time of the initial order (that was partially executed) does not change and is not equal to the time of its trade.
  • The history table is sorted by order time (ORDER_TIME_SETUP) but not by deal time. So if we do HistorySelect from DEAL_TIME, we can not get the corresponding order into the history table.
  • HistorySelectByPosition always returns the necessary set of deals/orders.
  • You can calculate the slippage for any trade.

In your experience, is there any general pattern in what cases/modes of working which MT5 uses?

3. Ultimately, have there ever been any real situations where "POSITION_TICKET != POSITION_IDENTIFIER" ?

POSITION_TICKET != POSITION_IDENTIFIER
POSITION_TICKET != POSITION_IDENTIFIER
  • 2018.02.12
  • www.mql5.com
зная id позиции можно ли без перебора узнать тикет позиции...
 
mktr8591:
When calling a macro, it is possible to omit a parameter (leave it out), and sometimes you want to specifically allow a macro to work with an unspecified parameter.
It turns out that an unspecified parameter in any macro is treated by the compiler as an empty string?
 
fxsaber:
So it turns out that an unspecified parameter in any macro is treated by the compiler as an empty string?

In a way, yes, although maybe "like an empty space" is a better word. Difficult to articulate clearly :-(.

But #p definitely turns into string ==""

 
mktr8591:

In a way, yes, although maybe "like an empty space" is a better word. Difficult to articulate clearly :-(.

But #p definitely turns into string ==""

Thanks, interesting nuance.

 
Особенности языка mql5, тонкости и приёмы работы
Особенности языка mql5, тонкости и приёмы работы
  • 2021.04.03
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач...
 
mktr8591:

Back to the question of partial performance again.

1. Please clarify on point 3: "You can close a formed position without removing the Partial Put Option. But if after that the order is triggered, a trade will open with a ticket equal to the ticket of the position you closed before. That is, there may be a situation where you close a position with a certain ticket. And then a position appears again with the same ticket."
In this case, was POSITION_IDENTIFIER equal to POSITION_TICKET or not?

2. Earlier in the "POSITION_TICKET != POSITION_IDENTIFIER" branch you demonstrated a different logic of MT5.

https://www.mql5.com/ru/forum/227423/page2#comment_6543129

In your experience, did you show any general pattern in which cases/modes of operation which MT5 scheme applies?

3. Ultimately, have there ever been any real situations where "POSITION_TICKET != POSITION_IDENTIFIER" ?

Both links talk about different implementations of partial execution. This is determined by the broker's software, not MT5.

No mismatch between ticket and ID has ever been encountered.

 
Thank you.
 

Forum on trading, automated trading systems and strategy testing

Libraries: Usage

fxsaber, 2021.05.01 14:17

GetMicrosecondCount may output a value less than on the previous call (without ULONG overflow). Examples of such situations.
2021.04.29 06:43:31.915   Alert: NewValue = 296000074313, PrevValue = 296001329284

2021.04.29 06:43:32.149   Alert: NewValue = 296086250613, PrevValue = 296087264090

2021.04.29 06:43:31.868   Alert: NewValue = 295129291901, PrevValue = 295130576710

2021.04.29 06:43:32.180   Alert: NewValue = 295955613012, PrevValue = 295956589070

2021.04.29 06:43:32.180   Alert: NewValue = 295146223171, PrevValue = 295147199454

2021.04.29 06:43:32.149   Alert: NewValue = 295065995432, PrevValue = 295067005968

2021.04.29 06:43:32.149   Alert: NewValue = 295078776581, PrevValue = 295079787357

Each line is obtained by different EAs on three MT4 terminals.

And on MT5 this sort of thing happens, but much less frequently on MT4.

Be careful.

 
Comments not related to this topic have been moved to "Questions from MQL5 MT5 MetaTrader 5 beginners".
Reason: