MT5 y la velocidad en acción - página 4

 
Entiendo que todo depende del equipo
 
Alexsandr San:
Entiendo que depende del equipo

No, en absoluto.

2020.05.29 15:08:44.938 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-6850 K  @ 3.60 GHz, 23 / 31 Gb memory, 43 / 226 Gb disk, IE 11, UAC, Admin, GMT+3
 
Alexsandr San:
Supongo que depende del hardware.

No lo creo ))))

Y ni siquiera desde un ordenador ocupado...

 
prostotrader:

No, en absoluto.

sí! su máquina y la anterior tienen resultados diferentes - así que estoy equivocado, no los medios de poder

 
Aleksey Mavrin:

¿Qué es onMain? ¿Cómo puede haber más de un evento en la cola en onMain si cada evento llama a onMain para manejar la cola?

OnMain es una función. No se trata de código real, sino de un caso especial - una respuesta a la afirmación "No hay manera de conocer el estado de la cola real actualmientras se ejecuta la función OnMain".Es un enfoque diferente de los cálculos en sí mismos

 
A100:

OnMain es una función. No es el código real, sino un caso especial - una respuesta a la afirmación "No hay manera de conocer el estado de la cola real actualdurante la ejecución de la función OnMain".Se trata de un enfoque diferente de los cálculos en sí

Así que, por si acaso, OnMain...

:) ;)
 
fxsaber:


En Asesores de Combate, he envuelto funciones por todas partes en lugares sospechosos a _B(FuncName(...), AlertTime). He aquí un breve extracto del registro de las entradas más recientes.

La columna de tiempo muestra la frecuencia con la que se producen las congelaciones.

Estás sustituyendo conceptos.

Aquí está su declaración original:

Desgraciadamente, esa llamada a HistorySelect dura entre 5 y 30 milisegundos (lo he medido yo mismo en Release-EX5). Cuando el Asesor Experto hace varias actualizaciones de este tipo en OnTick (de buena manera, debe hacerse después de cualquier pausa. Por ejemplo, después de cada OrderSend.), entonces todo se vuelve insanamente caro/largo. HistorySelect puede sumar varios segundos en un solo OnTick.

Incluso en su terminal, el tiempo medio de 0,2 ms por llamada es sensiblemente inferior a los valores especificados en la declaración original.

Ahora dices que a veces el tiempo de ejecución de una función puede ser notablemente más largo que la media. Esta es una pregunta diferente.

Cualquier petición de HistorySelect( ) es una llamada en toda regla a las bases de los terminales bajo sincronizadores. Esto es inevitable. Sí, teniendo en cuenta la presencia de la sincronización de acceso, no podemos garantizar un tiempo muy corto de ejecución de esta función.

La solución propuesta añadiendo las funciones HistoryDealsSelect() e HistoryOrdersSelect() no cambia absolutamente nada en este sentido.

El script para comprobar el tiempo máximo y medio:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---
   ulong start,end,max_time=0,avr_time=0;
   int   count=100000;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last tick time. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   Tick.time=(Tick.time/86400)*86400;
   max_time=0;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one last day HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last day. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   HistorySelect(0, INT_MAX);
   Print("Orders total: ",HistoryOrdersTotal());
  }
2020.05.29 17:22:04.195 TestHistorySelect (EURJPY,H1)   Last tick time. Selected orders: 0; max time: 0.034 ms; avr time: 0.001 ms; 100000 iterations
2020.05.29 17:22:06.771 TestHistorySelect (EURJPY,H1)   Last day. Selected orders: 141; max time: 0.101 ms; avr time: 0.027 ms; 100000 iterations
2020.05.29 17:22:08.039 TestHistorySelect (EURJPY,H1)   Orders total: 31448
 
Anton:

Un script para comprobar los tiempos máximos y medios:

No voy a comentar su opinión antes citada. Aquí está el resultado de la ejecución de su script.

Más concretamente, no podía esperar a que terminara, así que cambié el número de iteraciones de 100K a 1K.

        Last tick time. Selected orders: 0; max time: 3.880 ms; avr time: 1.315 ms; 1000 iterations
        Last day. Selected orders: 2061; max time: 7.131 ms; avr time: 4.309 ms; 1000 iterations
        Orders total: 50113

¿Merece esto siquiera una calificación satisfactoria?

Mira lo absurdo de la situación. ¡Para averiguar estúpidamente el número de ofertas tenemos que llamar a HistorySelect! Esto, por decirlo suavemente, no es racional.


En el mejor de los casos, paso decenas de milisegundos en cada tic sólo por HistorySelect.

 
A100:

En su forma más simple:

Sólo hay que cambiar el enfoque de los cálculos en sí mismos (hacer la vuelta intermedia con la frecuencia que requiera la tarea). Pero si es complicado, considera en la primera etapa que OnMain está ausente para ti (pones el código principal no en OnMain sino en OnTrade2XX), por lo tanto no necesitas aprender nada en OnMain

Gracias, es exactamente como lo entendí desde el principio y por eso dije que no lo entendía del todo. He aquí un ejemplo de un escenario sencillo.


Se hace un OrderSend. Si una determinada posición no se ha cerrado en la marca justo después del OrderSend, se hace otro OrderSend. Todo esto es una lógica, que hay que programar. No se utiliza Async.


Ahora la situación que ocurrió para nuestro robot. Has enviado un OrderSend y mientras se ejecuta el Limiter se ha disparado y se ha ejecutado el TP de la posición mencionada anteriormente.


¿Cuál es la implementación del robot de forma esquemática? No sé cómo implementarlo sin frenar HistorySelect o OnTradeTransaction-spy muleta que da acceso a toda la historia de las transacciones en cualquier lugar del código. Si se implementara un mecanismo de acceso a la cola de eventos, el ejemplo anterior se resolvería de forma elemental.


Todos los fuertes en MT5, incluyendo los desarrolladores, por favor muéstrenme cómo implementar esta( dos líneasen negrita arriba) poco complicada (me da miedo incluso mencionar compleja) lógica de trading.

 
A100:

OnMain es una función. Este no es el código real, sino un caso especial - una respuesta a la afirmación " No hay manera de conocer el estado de la cola real actual durante la ejecución de la función OnMain".Este es un enfoque diferente de los cálculos en sí

Bueno, lo es, ¿no? Y eso es lo que los chicos estaban hablando. Para implementarlo, hay que cambiar la estructura de ejecución de los programas MQL, ya sea a) como mínimo en una de dos hilos o b) añadir un mecanismo de acceso y gestión de colas.

Con la estructura actual, su esquema propuesto es imposible de aplicar.