Características del lenguaje mql5, sutilezas y técnicas - página 201

 
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(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:

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.

  1. Si se cuelga una orden limitada parcial, la pestaña "Órdenes y operaciones" no mostrará la operación generada.
  2. 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.
  3. 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.
  4. 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.

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_6543129

fxsaber:

Conclusiones

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"?

POSITION_TICKET != POSITION_IDENTIFIER
POSITION_TICKET != POSITION_IDENTIFIER
  • 2018.02.12
  • www.mql5.com
зная id позиции можно ли без перебора узнать тикет позиции...
 
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?
 
fxsaber:
¿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 ==""

 
mktr8591:

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.

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

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_6543129

Segú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.

 
Gracias.
 

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.
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

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.

 
Los comentarios no relacionados con este tema han sido trasladados a "Preguntas de los principiantes de MQL5 MT5 MetaTrader 5".