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(conststring p = NULL) {return"" == p;}
template<typename T> bool __hlp_macro_func(T p) {returntrue;}
template<typename T> bool __hlp_macro_func(T& p) {returntrue;}
template<typename T> bool __hlp_macro_func(T& p[]) {returntrue;}
//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; };
voidOnStart()
{
//---Print(IS_PARAMETER_SET()); //falsePrint(IS_PARAMETER_SET("")); //truePrint(IS_PARAMETER_SET("test")); //truePrint(IS_PARAMETER_SET(NULL)); //truePrint(IS_PARAMETER_SET(0)); //truePrint(IS_PARAMETER_SET(1)); //truestring str;
Print(IS_PARAMETER_SET(str)); //trueint 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)); //1Print(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
}
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.
If a partial limit order is hanging, the tab "Orders and trades" will not show the generated trade.
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.
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.
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.
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.
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" ?
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?
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.
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:
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.
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_6543129Conclusions
If we assume that this is normal behavior of MT5, and not a peculiarity of the broker's hack, then
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" ?
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.
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 ==""
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.
@fxsaber
Look up this issue, please: https://www.mql5.com/ru/forum/170952/page201#comment_21964923
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_6543129In 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.
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.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.