Cuando se llama a una macro se puede no especificar ningún parámetro (omitirlo), a veces se quiere permitir específicamente que una macro funcione con un parámetro no especificado.
Para estos casos, aquí hay algunas macros auxiliares.
1. a veces quieres determinar dentro de tu macro si un parámetro ha sido establecido o no. IS_PARAMETER_SET(p) define una expresión, que devuelve true si p está establecido (incluso si la variable de cadena ==NULL).
Atención: ¡¡¡la expresión se evalúa después del preprocesamiento en tiempo de compilación!!!, es decir, no se puede utilizar para implementar algo como #ifdef IS_PARAMETER_SET(p) #else (esto también se aplica a otras macros a continuación)
2. Si necesita convertir explícitamente el valor de un parámetro en una cadena, para evitar un error de compilación con un parámetro no especificado, puede utilizar __EVAL_STR(p). Si p no está definido o está definido explícitamente con un literal NULL, devuelve "". No es aplicable a las matrices, estructuras y clases.
La conversión explícita de un parámetro a un número es __EVAL_NON_STR(p). Si p no está establecido, devuelve 0. ¡No funciona cuando p es una cadena!
Código y ejemplos de uso:
//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
}
El siguiente código en la cuenta demode RannForex-Server puede reproducir inmediatamente esta situación ejecutando este asesor.
Resultado.
Por cierto, el script muestra (no siempre la primera vez) un error en la ejecución sincrónica de OrderSend.
Después de la ejecución de OrderSend durante unas decenas/centenares de milisegundos, el precio de la orden es el antiguo, y no el que fue colocado con éxito por OrderSend.
Volviendo al tema de los billetes idénticos, podemos sacar algunas conclusiones.
Si se cuelga una orden limitada parcial, la pestaña "Órdenes y operaciones" no mostrará la operación generada.
En una cobertura, una sola orden puede generar múltiples operaciones IN con diferentes precios. El resultado será un precio de apertura fraccionado (en relación con los pips) de la posición.
Puede cerrar la posición generada sin eliminar la venta parcial. Pero si después se activa la orden pendiente, se abrirá una operación con el ticket, igual al ticket de la posición, que se cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo ticker.
La ejecución parcial puede implementarse de forma diferente, dependiendo del software del corredor. Lo anterior es una implementación estándar de MT5.
Si alguien ha conseguido reproducirlo en otro servidor de comercio, por favor comparta el nombre.
1. Por favor, aclare el punto 3: "Puede cerrar la posición que ha formado sin eliminar el aplazamiento parcial. Pero si después la orden se activa, se abrirá una operación con un ticket igual al de la posición que cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo billete". En este caso, ¿era POSITION_IDENTIFIER igual a POSITION_TICKET o no?
2. Anteriormente, en el hilo "POSITION_TICKET != POSITION_IDENTIFIER" demostró una lógica diferente de MT5.
Si asumimos que esto es un comportamiento normal de MT5, y no una peculiaridad del hack del broker, entonces
ORDER_STATE_PARTIAL no existe en los pedidos históricos.
Las órdenes que se ejecutan siempre tienen el estado ORDER_STATE_FILLED.
Cuando una orden se ejecuta parcialmente, el servidor comercial crea una nueva orden de mercado correspondiente (ORDER_REASON_CLIENT - incluso si la orden inicial se coloca automáticamente (EXPERT)).
La antigua orden en vivo (el ticket no se modifica) sigue pendiente con un volumen reducido (ORDER_VOLUME_CURRENT).
En este caso, el antiguo pedido vivo tiene el estado ORDER_STATE_PARTIAL. En realidad, esta bandera es el resultado de la comparación de ORDER_VOLUME_CURRENT y ORDER_VOLUME_INITIAL.
Todas las posiciones abiertas reciben ID == OrderTicket. Donde OrderTicket es el ticket generado por el servidor de comercio.
Una operación siempre tiene exactamente una orden histórica y su estado es ORDER_STATE_FILLED.
Cada orden histórica ejecutada tiene exactamente una operación.
El ORDER_VOLUME_INITIAL de cualquier orden ejecutada es igual al volumen para el que se ejecutó. Es decir, incluso la orden inicial que fue cancelada tiene un ORDER_VOLUME_INITITAL que es igual al volumen de la operación que generó.
La hora de la orden inicial (que fue parcialmente ejecutada) no cambia y no es igual a la hora de su negociación.
La tabla del historial está ordenada por la hora del pedido (ORDER_TIME_SETUP) pero no por la hora de la operación. Así que si hacemos HistorySelect desde DEAL_TIME, no podemos obtener la orden correspondiente en la tabla de historial.
HistorySelectByPosition siempre devuelve el conjunto necesario de ofertas/órdenes.
Puede calcular el deslizamiento de cualquier operación.
Según su experiencia, ¿hay algún patrón general en los casos/modos de trabajo que utiliza MT5?
3. En definitiva, ¿ha habido alguna situación real en la que "POSITION_TICKET != POSITION_IDENTIFIER"?
mktr8591: Cuando se llama a una macro, es posible omitir un parámetro (saltárselo), y a veces se quiere permitir específicamente que una macro funcione con un parámetro no especificado.
Resulta que un parámetro no especificado en cualquier macro es tratado por el compilador como una cadena vacía?
1. Por favor, aclare el punto 3: "Puede cerrar una posición formada sin eliminar la opción de venta parcial. Pero si después la orden se activa, se abrirá una operación con un ticket igual al de la posición que cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo billete". En este caso, ¿era POSITION_IDENTIFIER igual a POSITION_TICKET o no?
2. Anteriormente, en la rama "POSITION_TICKET != POSITION_IDENTIFIER" demostró una lógica diferente de MT5.
Para estos casos, aquí hay algunas macros auxiliares.
1. a veces quieres determinar dentro de tu macro si un parámetro ha sido establecido o no. IS_PARAMETER_SET(p) define una expresión, que devuelve true si p está establecido (incluso si la variable de cadena ==NULL).
Atención: ¡¡¡la expresión se evalúa después del preprocesamiento en tiempo de compilación!!!, es decir, no se puede utilizar para implementar algo como #ifdef IS_PARAMETER_SET(p) #else (esto también se aplica a otras macros a continuación)
2. Si necesita convertir explícitamente el valor de un parámetro en una cadena, para evitar un error de compilación con un parámetro no especificado, puede utilizar __EVAL_STR(p). Si p no está definido o está definido explícitamente con un literal NULL, devuelve "". No es aplicable a las matrices, estructuras y clases.
La conversión explícita de un parámetro a un número es __EVAL_NON_STR(p). Si p no está establecido, devuelve 0. ¡No funciona cuando p es una cadena!
Código y ejemplos de uso:
El siguiente código en la cuenta demode RannForex-Server puede reproducir inmediatamente esta situación ejecutando este asesor.
Resultado.
Por cierto, el script muestra (no siempre la primera vez) un error en la ejecución sincrónica de OrderSend.
Después de la ejecución de OrderSend durante unas decenas/centenares de milisegundos, el precio de la orden es el antiguo, y no el que fue colocado con éxito por OrderSend.
Volviendo al tema de los billetes idénticos, podemos sacar algunas conclusiones.
Si alguien ha conseguido reproducirlo en otro servidor de comercio, por favor comparta el nombre.
Cadena de búsqueda: Oshibka 010.
Volvemos a la cuestión de la ejecución parcial.
1. Por favor, aclare el punto 3: "Puede cerrar la posición que ha formado sin eliminar el aplazamiento parcial. Pero si después la orden se activa, se abrirá una operación con un ticket igual al de la posición que cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo billete".
En este caso, ¿era POSITION_IDENTIFIER igual a POSITION_TICKET o no?
2. Anteriormente, en el hilo "POSITION_TICKET != POSITION_IDENTIFIER" demostró una lógica diferente de MT5.
https://www.mql5.com/ru/forum/227423/page2#comment_6543129Conclusiones
Si asumimos que esto es un comportamiento normal de MT5, y no una peculiaridad del hack del broker, entonces
Según su experiencia, ¿hay algún patrón general en los casos/modos de trabajo que utiliza MT5?
3. En definitiva, ¿ha habido alguna situación real en la que "POSITION_TICKET != POSITION_IDENTIFIER"?
Cuando se llama a una macro, es posible omitir un parámetro (saltárselo), y a veces se quiere permitir específicamente que una macro funcione con un parámetro no especificado.
¿Así que resulta que un parámetro no especificado en cualquier macro es tratado por el compilador como una cadena vacía?
En cierto modo, sí, aunque tal vez "como un espacio vacío" sea una palabra mejor. Difícil de articular claramente :-(.
Pero #p se convierte definitivamente en cadena ==""
En cierto modo, sí, aunque tal vez "como un espacio vacío" sea una palabra mejor. Difícil de articular claramente :-(.
Pero #p se convierte definitivamente en cadena ==""
Gracias, un matiz interesante.
@fxsaber
Busque este tema, por favor: https://www.mql5.com/ru/forum/170952/page201#comment_21964923
Volvemos a la cuestión del rendimiento parcial.
1. Por favor, aclare el punto 3: "Puede cerrar una posición formada sin eliminar la opción de venta parcial. Pero si después la orden se activa, se abrirá una operación con un ticket igual al de la posición que cerró antes. Es decir, puede darse una situación en la que se cierre una posición con una determinada entrada. Y luego vuelve a aparecer una posición con el mismo billete".
En este caso, ¿era POSITION_IDENTIFIER igual a POSITION_TICKET o no?
2. Anteriormente, en la rama "POSITION_TICKET != POSITION_IDENTIFIER" demostró una lógica diferente de MT5.
https://www.mql5.com/ru/forum/227423/page2#comment_6543129Según su experiencia, ¿ha mostrado algún patrón general en qué casos/modos de operación se aplica el esquema de MT5?
3. En definitiva, ¿ha habido alguna situación real en la que "POSITION_TICKET != POSITION_IDENTIFIER"?
Ambos enlaces hablan de diferentes implementaciones de la ejecución parcial. Esto lo determina el software del broker, no MT5.
Nunca se ha encontrado una falta de coincidencia entre el billete y el documento de identidad.
Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias
Bibliotecas: Uso
fxsaber, 2021.05.01 14:17
GetMicrosecondCount puede arrojar un valor menor que en la llamada anterior (sin desbordamiento de ULONG). Ejemplos de estas situaciones.Cada línea es obtenida por diferentes EAs en tres terminales MT4.
Y en MT5 ocurren este tipo de cosas, pero con mucha menos frecuencia en MT4.
Ten cuidado.