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

 
fxsaber:

Creo que este muro MQ no saldrá adelante sin el apoyo de los miembros del foro. El código es corto, los profesionales deberían ser capaces de resolverlo rápidamente. No hay ningún defecto. Se muestra claramente que los precios a través de las posiciones se obtienen mucho más rápido que a partir de Market Watch. Cómo MQ no puede ver lo obvio, no lo entiendo.

1. Su prueba realmente cuenta un micro porcentaje de iteraciones debido a la condición

if (Interval##A > 100)

En esencia, sólo se cuentan las anomalías en las que el procesador se sobrecarga de tareas y pospone la realización de la tarea dada en el estante lejano, ya que más del 99% de las iteraciones se realizan en menos de 1 microsegundo.

E incluso si se establece la condición >0, sigue sin haber objetividad.

2. La medición del tiempo de estas operaciones rápidas sólo debe hacerse como tiempo de ciclo completo, no de una sola iteración.

3. Pero como el ciclo en su ejemplo está limitado a 10 segundos (¡Por qué! Para los ticks creo que 0,1 segundos es suficiente. Porque bien puede ocurrir que lleguen 3 ticks en un segundo, y que los tres ticks se ejecuten durante 10 segundos cada uno, y en paralelo), por lo que no es necesario temporizar. Es más fácil calcular cuántas iteraciones se ejecutarán en un tiempo determinado. Cuanto más, más productividad.

He modificado su código "un poco". Creo que mi variante refleja mejor la realidad.

El cálculo se hace de uno en uno, para no mezclar las dos variantes. Los números pares son paraSYMBOL_BID, los impares - para GetBid().

He añadido sumas y su salida por si acaso, como un intento de engañar al compilador contra la optimización.
El resultado de la salida es acumulativo.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
#define  TimeLoop 125  // 15.625*8  

bool GetPosition(const int Type = OP_BUY)
  {
   bool Res = false;
   for(int i = PositionsTotal() - 1; (i >= 0) && !Res; i--)
      Res = PositionGetTicket(i) && (PositionGetInteger(POSITION_TYPE) == Type) &&
            (PositionGetString(POSITION_SYMBOL) == _Symbol);
   return(Res);
  }

// Альтернативный способ получения Bid-цены текущего символа.
// Запускать только на демо-счетах.
double GetBid()
  {
   static const TICKET_TYPE Ticket = GetPosition() ? PositionGetInteger(POSITION_TICKET) : OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0);
   return(PositionSelectByTicket(Ticket) ? PositionGetDouble(POSITION_PRICE_CURRENT) : 0);
  }

#define  TOSTRING(A) ", "#A + " = " + (string)(A)


long N1=0;
long N2=0;
long n=0;
double sum1=0;
double sum2=0;

const bool Init = EventSetTimer(10) && GetBid(); // Будем выводить статистику каждый 10 секунд.

//+------------------------------------------------------------------+

void OnTick()
  {
//  return;
   const uint StartTime = GetTickCount();
   if(n%2==0)
      while(!IsStopped() && (GetTickCount() - StartTime < TimeLoop))
        {
         sum1+=SymbolInfoDouble(_Symbol, SYMBOL_BID);
         N1++;
        }
   else
      while(!IsStopped() && (GetTickCount() - StartTime < TimeLoop))
        {
         sum2+=GetBid();
         N2++;
        }
   if(n%2==0 && n>1)
      if (N1>N2) Print(_Symbol+": SYMBOL_BID быстрее GetBid() в " + DoubleToString(double(N1)/N2,2) + " раза. Среднее время одной итерации: SYMBOL_BID - " + DoubleToString((TimeLoop*1000000.0*n/2)/N1,2) + " ns, GetBid() - " + DoubleToString((TimeLoop*1000000.0*n/2)/N2,2) + " ns" + TOSTRING(sum1) + TOSTRING(sum2));
      else       Print(_Symbol+": GetBid() быстрее SYMBOL_BID в " + DoubleToString(double(N2)/N1,2) + " раза. Среднее время одной итерации: SYMBOL_BID - " + DoubleToString((TimeLoop*1000000.0*n/2)/N1,2) + " ns, GetBid() - " + DoubleToString((TimeLoop*1000000.0*n/2)/N2,2) + " ns" + TOSTRING(sum1) + TOSTRING(sum2));
      n++;
  }
//+------------------------------------------------------------------+

Mi resultado:

2020.10.26 19:26:46.193 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.97 раза. Среднее время одной итерации: SYMBOL_BID - 45.80 ns, GetBid() - 135.80 ns, sum1 = 106706334.7283292, sum2 = 35987491.50911281
2020.10.26 19:26:46.193 FxSaberBidSpeed (EURUSD,M1)     EURUSD: SYMBOL_BID быстрее GetBid() в 2.90 раза. Среднее время одной итерации: SYMBOL_BID - 45.10 ns, GetBid() - 130.82 ns, sum1 = 34042649.2788716,  sum2 = 11735304.45101236
2020.10.26 19:26:47.085 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.95 раза. Среднее время одной итерации: SYMBOL_BID - 45.57 ns, GetBid() - 134.55 ns, sum1 = 110131593.3516681, sum2 = 37303001.98488424
2020.10.26 19:26:52.397 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.99 раза. Среднее время одной итерации: SYMBOL_BID - 45.48 ns, GetBid() - 135.90 ns, sum1 = 113269505.1945728, sum2 = 37903458.6724181
2020.10.26 19:26:59.412 FxSaberBidSpeed (EURUSD,M1)     EURUSD: SYMBOL_BID быстрее GetBid() в 2.85 раза. Среднее время одной итерации: SYMBOL_BID - 45.16 ns, GetBid() - 128.57 ns, sum1 = 36611618.7279973,  sum2 = 12858907.51985167
2020.10.26 19:27:00.131 FxSaberBidSpeed (BTCUSD,M1)     BTCUSD: SYMBOL_BID быстрее GetBid() в 2.78 раза. Среднее время одной итерации: SYMBOL_BID - 47.10 ns, GetBid() - 130.88 ns, sum1 = 305215291120.0239, sum2 = 109832697267.1495
2020.10.26 19:27:03.303 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.96 раза. Среднее время одной итерации: SYMBOL_BID - 45.44 ns, GetBid() - 134.61 ns, sum1 = 116279675.0471961, sum2 = 39248002.75579567
2020.10.26 19:27:06.318 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 3.01 раза. Среднее время одной итерации: SYMBOL_BID - 45.17 ns, GetBid() - 135.96 ns, sum1 = 119877506.6663743, sum2 = 39829996.08171722
2020.10.26 19:27:06.709 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 3.01 раза. Среднее время одной итерации: SYMBOL_BID - 44.92 ns, GetBid() - 135.42 ns, sum1 = 123505976.1123297, sum2 = 40965170.16304104
2020.10.26 19:27:07.803 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.99 раза. Среднее время одной итерации: SYMBOL_BID - 44.84 ns, GetBid() - 134.00 ns, sum1 = 126664503.6443297, sum2 = 42385980.37108831
Como puedes ver, la diferencia de rendimiento es tres veces mayor a favor de la versión estándar.
 
Nikolai Semko:


Como puede ver, la diferencia de rendimiento es tres veces mayor que la de la versión original.

¿La versión original de fxsaber muestra la ventaja de GetBid, o se trata de un PC más potente/menos cargado?

 
Andrey Khatimlianskii:

¿La versión original de fxsaber muestra la ventaja de GetBid, o es un PC más potente/menos cargado?

Su variante también mostró la ventaja de GetBid a plena carga de la CPU. Pero al mismo tiempo mi variante muestra tres veces la ventaja de la función regular con la misma carga.
Esto
se debe a que mi variante tiene en cuenta el tiempo medio de todas las iteraciones de obtener el precio de la oferta y su sólo una pequeña fracción con cuelgues anómalos.
Quién sabe por qué razón el procesador se atasca con la función regular (cuando el retraso es superior a 100 µ) en un "minuto" difícil. Pero aún así el tiempo medio es tres veces menor para la función regular

Así, por ejemplo, si (Intervalo##A > 100) este es el caso:

mientras que si (Intervalo##A > 0) ya es bastante diferente, mostrando una distribución aleatoria de retrasos anormales entre la versión regular y la alternativa de obtener el precio de la Oferta

al mismo tiempo mi prueba con la misma carga de CPU muestra:

2020.10.26 22:16:10.569 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.79 раза. Среднее время одной итерации: SYMBOL_BID - 57.95 ns, GetBid() - 161.43 ns, sum1 = 108105265.450882, sum2 = 38804020.20301527
2020.10.26 22:16:12.146 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.79 раза. Среднее время одной итерации: SYMBOL_BID - 57.81 ns, GetBid() - 161.06 ns, sum1 = 111212159.8857315, sum2 = 39917412.88663763
2020.10.26 22:16:13.741 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.79 раза. Среднее время одной итерации: SYMBOL_BID - 57.37 ns, GetBid() - 159.91 ns, sum1 = 114942034.0034028, sum2 = 41233865.03452455
2020.10.26 22:16:14.740 FxSaberBidSpeed (EURUSD,M1)     EURUSD: SYMBOL_BID быстрее GetBid() в 3.18 раза. Среднее время одной итерации: SYMBOL_BID - 52.88 ns, GetBid() - 167.92 ns, sum1 = 75470423.51597476, sum2 = 23764764.64380601
2020.10.26 22:16:15.756 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.78 раза. Среднее время одной итерации: SYMBOL_BID - 57.30 ns, GetBid() - 159.06 ns, sum1 = 117956798.0483066, sum2 = 42491447.24894404
2020.10.26 22:16:17.646 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.77 раза. Среднее время одной итерации: SYMBOL_BID - 57.19 ns, GetBid() - 158.36 ns, sum1 = 121056970.4066543, sum2 = 43721243.0341278
2020.10.26 22:16:20.146 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.76 раза. Среднее время одной итерации: SYMBOL_BID - 57.14 ns, GetBid() - 157.85 ns, sum1 = 124053724.3725583, sum2 = 44907061.11418578
2020.10.26 22:16:21.553 FxSaberBidSpeed (EURUSD,M1)     EURUSD: SYMBOL_BID быстрее GetBid() в 3.15 раза. Среднее время одной итерации: SYMBOL_BID - 52.80 ns, GetBid() - 166.11 ns, sum1 = 78375839.87008552, sum2 = 24913626.42960918
2020.10.26 22:16:24.865 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.77 раза. Среднее время одной итерации: SYMBOL_BID - 56.94 ns, GetBid() - 157.50 ns, sum1 = 127392085.5933389, sum2 = 46051851.71182434
2020.10.26 22:16:27.678 FxSaberBidSpeed (USDCAD,M1)     USDCAD: SYMBOL_BID быстрее GetBid() в 2.77 раза. Среднее время одной итерации: SYMBOL_BID - 57.13 ns, GetBid() - 158.30 ns, sum1 = 129851046.9417646, sum2 = 46862113.16739535

Por lo tanto, creo que la versión de fxsaber de la prueba está lejos de ser objetiva.

No he cargado la CPU con agentes, sino con este script. Era más eficiente.

Archivos adjuntos:
LSD.mq5  6 kb
 

tras una ligera modificación de la prueba fxsaber para demostrar claramente qué porcentaje de iteraciones se tiene en cuenta en los cálculos:

2020.10.26 22:45:03.679 FxSaberBidSpeed (USDCAD,M1)     Alert: , TimeBid1-TimeBid2 = 2142416 mcs., TimeBid1 = 2858669, TimeBid2 = 716253,  Всего итераций - 31456223, из них принято во внимание, NBid1 = 3015, NBid2 = 1714
2020.10.26 22:45:05.739 FxSaberBidSpeed (BTCUSD,M1)     Alert: , TimeBid1-TimeBid2 = 1521696 mcs., TimeBid1 = 2282285, TimeBid2 = 760589,  Всего итераций - 31417549, из них принято во внимание, NBid1 = 1794, NBid2 = 1418
2020.10.26 22:45:06.006 FxSaberBidSpeed (USDJPY,M1)     Alert: , TimeBid1-TimeBid2 = 2241890 mcs., TimeBid1 = 3204507, TimeBid2 = 962617,  Всего итераций - 54138004, из них принято во внимание, NBid1 = 4401, NBid2 = 2083
2020.10.26 22:45:09.099 FxSaberBidSpeed (EURUSD,M1)     Alert: , TimeBid1-TimeBid2 = 1000828 mcs., TimeBid1 = 1496646, TimeBid2 = 495818,  Всего итераций - 10037824, из них принято во внимание, NBid1 = 2429, NBid2 = 1711
2020.10.26 22:45:14.803 FxSaberBidSpeed (USDCAD,M1)     Alert: , TimeBid1-TimeBid2 = 2676273 mcs., TimeBid1 = 3916168, TimeBid2 = 1239895, Всего итераций - 41606744, из них принято во внимание, NBid1 = 4935, NBid2 = 3790
2020.10.26 22:45:15.745 FxSaberBidSpeed (BTCUSD,M1)     Alert: , TimeBid1-TimeBid2 = 1521696 mcs., TimeBid1 = 2282285, TimeBid2 = 760589,  Всего итераций - 31417549, из них принято во внимание, NBid1 = 1794, NBid2 = 1418
2020.10.26 22:45:16.115 FxSaberBidSpeed (USDJPY,M1)     Alert: , TimeBid1-TimeBid2 = 2653810 mcs., TimeBid1 = 4195095, TimeBid2 = 1541285, Всего итераций - 64310228, из них принято во внимание, NBid1 = 6486, NBid2 = 3879
2020.10.26 22:45:19.834 FxSaberBidSpeed (EURUSD,M1)     Alert: , TimeBid1-TimeBid2 = 1949809 mcs., TimeBid1 = 3091755, TimeBid2 = 1141946, Всего итераций - 19435170, из них принято во внимание, NBid1 = 4724, NBid2 = 3547

es decir, aproximadamente el 0,01%.

Ya lo creo.
Si el tiempo medio de ejecución de SymbolInfoDouble(_Symbol, SYMBOL_BID) es de unos 50 nanosegundos, sólo se tienen en cuenta los que tienen un tiempo de ejecución superior a 100 000 nanosegundos.

Archivos adjuntos:
 
Nikolai Semko:

tras una ligera modificación de la prueba fxsaber para demostrar claramente qué porcentaje de iteraciones se tiene en cuenta en los cálculos:

es decir, aproximadamente el 0,01%.

Por supuesto.
Si el tiempo medio de ejecución de SymbolInfoDouble(_Symbol, SYMBOL_BID) es de unos 50 nanosegundos, sólo se cuentan las iteraciones superiores a 100 000 nanosegundos.

Podríamos haber hecho simplemente que la condición no fuera más de 100 µs, sino más de 3 µs. El resultado fue aparentemente el mismo. Se pensó en un estudio segmentado y en diferentes condiciones de ejecución puede haber una diferencia en diferentes segmentos y en diferentes secciones. Las prioridades de ejecución suelen hacerse en función de cualquier cosa. A poca carga unas prioridades, a mucha carga otras, a las críticas, las que no dejan que el ordenador se cuelgue y se cuelgue, y el rendimiento pasa a un segundo plano.

En general, operar con una carga superior al 70% del hardware no es correcto. Es un rendimiento casi crítico. La carga de hierro en los EA de combate no debe superar el 60%.

 
No estaré en mi ordenador durante un tiempo, así que seré breve.

En algotrading, a nadie le importa la temperatura media del hospital cuando hay ralentizaciones periódicas. Obtener precios en milisegundos es algo habitual. Y eso en un entorno de combate.

Si es posible obtener precios sin picos de retraso en momentos importantes de la negociación, entonces lucharé por esta misma oportunidad.

He demostrado con el código que esa muleta existe. Si quieres evitar los retrasos, utiliza la muleta.

Nadie aquí ha mirado el código comparando los precios recibidos cuando se trabaja con una secadora también. Y ahí, por decirlo suavemente, hay serias dudas.

El hecho es que la función regular se retrasa catastróficamente más a menudo que la muleta. Y no me importa que el tiempo medio sea casi nulo. Son los retrasos los que causan problemas durante la negociación

Quiere HFT - olvide incluso el nivel de milisegundos lentos por ahora.
 
¿ya tiene corredores de HFT?)
 
secret:
y ¿ya tiene corredores de HFT?)
Sí.
 
Igor Makanu:

intente probar SymbolInfoTick cuando hay un solo símbolo en la visión general del mercado y cuando hay docenas de símbolos, pero pida una herramienta - como en su ejemplo

hay una alta probabilidad de que el servidor esté enviando tráfico comprimido y que SymbolInfoTick esté experimentando esta ralentización intermitente al descomprimir los datos

es decir, cuando hay muchos símbolos, se producirán caídas más frecuentes o profundas en el tiempo de prueba

En las construcciones recientes, la recepción del flujo de ticks no tiene ningún efecto, ni siquiera teóricamente. Prácticamente, SymbolInfoTick ya funciona con caché, pero algunos ciudadanos siguen buscando un gato negro.

No veo el sentido de hacer pruebas con el procesador cargado al 80%.

Ni siquiera está al 80% en la prueba. Hay 6 agentes funcionando en 4 núcleos, es decir, 100% garantizado.

La única cuestión es cómo maneja la situación el programador de tareas de su sistema. Al mismo tiempo, se está afirmando que la culpa es de la implementación del terminal.

Es decir, se crea artificialmente una situación en la que un ordenador se sobrecarga, en la que literalmente todo en él se ralentiza, y entonces se hacen algunas reclamaciones en forma de "Oh, mira, por qué el terminal se retrasa a veces".

Cerremos los ojos al hecho de que incluso en tales condiciones es "alrededor del 0,01%" - ¡al diablo con los detalles! Basta con decir que "a nadie le importa la temperatura media del hospital", "los desfases causan problemas al operar" y "queremos HFT".

Además, por supuesto que queremos HFT en 20 expertos en un viejo escritorio de oficina o una máquina virtual muerta.

PS PositionSelectByTicket() en su implementación ciertamente tiene acceso a un recurso compartido con sincronización de acceso. Y si no seleccionas la posición en cada llamada, estás leyendo el precio antiguo. Era más fácil hacer un "snapshot" a través de SymbolInfoDouble.

Ордерa, позиции и сделки в MetaTrader 5
Ордерa, позиции и сделки в MetaTrader 5
  • www.mql5.com
Конечной целью трейдера является извлечение прибыли посредством торговых операций на финансовых рынках. В этой статье дается описание терминов и процессов торговой платформы MetaTarder 5, знание которых необходимо для правильного понимания работы торговых функций языка MQL5. Ордера — это принятые торговым сервером запросы на совершение торговых...
 
¿puede el núcleo en tiempo real ayudar de alguna manera?