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

 
Renat Fatkhullin:

Aceleración por un factor de diez en casos de acceso paralelo masivo.

En otros casos, sólo se actualiza el procesador, la memoria y el sistema operativo.

En PM, registros comparativos de la misma máquina.

 
fxsaber:

Esta es una llamada única de CopyTicks. Se hace con el fin de hacer un backtest virtual para estos ticks en OnInit, y luego continuar en tiempo real, alimentando sólo ticks frescos.

Como compromiso, propongo liberar la memoria en la Terminal inmediatamente después del CopyTicks llamado en OnInit. Entonces no tenemos que introducir una función de enfriamiento forzado para CopyTicks.

Ahora mismo la versión de refrigeración en sueño es muy muleta. Pero más arriba he mostrado cómo esta muleta ahorra memoria.


Ahora resulta que 20 Asesores Expertos funcionan rápido incluso en VPS lentos. Pero ponerlos en marcha es un problema serio.

No hace mucho tiempo, usted mismo ha realizado pruebas de estrés y ha exigido la emisión instantánea de garrapatas profundas en cada garrapata.

Es decir, tanto usted como el 100% de los demás desarrolladores han aplicado y aplicarán estrategias de solicitud de caché completas pendientes. Cada vez se escriben más peritajes costosos y frontales.

Por eso no vamos a suprimir las cachés ni mucho menos, sino que recomendamos poner 16-32gb de memoria y olvidarnos de problemas y retrasos.

Comportamiento y economía en VPS (mantener a 512 mb-1 gb) no nos importa en absoluto.

 
Renat Fatkhullin:

Tú mismo hacías pruebas de estrés no hace mucho tiempo y, de hecho, exigías que se hicieran pruebas de profundidad instantáneas en cada tic.

Es decir, tanto usted como el 100% de los demás desarrolladores han aplicado y aplicarán estrategias de solicitud de caché completas pendientes. Cada vez se escriben más peritajes costosos y frontales.

Por eso no vamos a suprimir las cachés ni mucho menos, sino que recomendamos poner 16-32gb de memoria y olvidarnos de problemas y retrasos.

Comportamiento y economía en VPS (para encajar en 512 mb-1gb) no nos importa en absoluto.

Arriba he complementado mi post con el código. Se trata de OnInit, no de otra cosa. CopyTicks caliente es muy necesario, pero no en OnInit.

 
fxsaber:

Como compromiso, sugiero que después de llamar a CopyTicks en OnInit, la memoria sea liberada inmediatamente en la Terminal.

En ningún caso.
¿Y si por el contrario levanto la caché en OnInit para poder trabajar con ella sin retrasos?

Es mejor introducir la función para descargar la caché del terminal.
Es necesario no sólo para los ticks, sino también para las series temporales y los indicadores (intente escribir un 5K para 5 instrumentos y 5 TFs).

@Renat?

 
Andrey Khatimlianskii:

¡No puede ser!
¿Y si elevo la caché en OnInit para poder trabajar con ella sin demora?

El caché de garrapatas sólo dura 10 segundos.

 

El script de detección del historial de ticks (el único software que se ejecuta en el Terminal) se come hasta 6GB si se toman las cotizaciones de cinco meses.

Cuanto más rápida sea la máquina e Internet, mayor será la carga de memoria. Es decir, las cachés internas del terminal se acumulan a unos pocos caracteres en 10 segundos.

 
Máquina rápida, nueve asesores.
2020.10.19 22:32:06.965         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1229 mcs.
2020.10.19 22:33:23.727         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1250 mcs.
2020.10.19 22:34:29.802         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1281 mcs.
2020.10.19 22:35:58.747         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1164 mcs.
2020.10.19 22:37:20.196         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1045 mcs.
2020.10.19 22:38:24.920         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1907 mcs.
2020.10.19 22:39:48.359         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1387 mcs.
2020.10.19 22:40:03.623         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1302 mcs.
2020.10.19 22:40:44.569         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1271 mcs.
2020.10.19 22:41:09.393         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1482 mcs.
2020.10.19 22:41:19.831         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1024 mcs.
2020.10.19 22:41:19.975         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 8026 mcs.
2020.10.19 22:41:50.137         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1040 mcs.
2020.10.19 22:42:05.876         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1346 mcs.
2020.10.19 22:43:21.478         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1523 mcs.
2020.10.19 22:43:21.557         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1245 mcs.
2020.10.19 22:43:21.843         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 4675 mcs.
2020.10.19 22:43:21.854         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 7567 mcs.
2020.10.19 22:44:01.181         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1052 mcs.
2020.10.19 22:44:33.124         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2714 mcs.
2020.10.19 22:44:54.967         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 13626 mcs.
2020.10.19 22:45:07.561         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2800 mcs.
No sé cómo superar esos retrasos. No se me ocurre ninguna otra forma de saber si hay un nuevo tick mientras se ejecuta OnTick.
 
fxsaber:
No se me ocurre otra forma de saber que hay un nuevo tick mientras se ejecuta OnTick.

Tres opciones.

// Идентификация нового тика
bool IsNewTick_CopyRates()
{
  static MqlRates PrevRates = {0};
  MqlRates Rates[1];
    
  const bool Res = (::CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, Rates) == 1) &&
//                   (_R(PrevRates) != Rates[0]); // TypeToBytes.mqh
                   ((Rates[0].time != PrevRates.time) ||
                    (Rates[0].tick_volume > PrevRates.tick_volume) ||
                    (Rates[0].close != PrevRates.close)); // Лишнее условие, но на всякий случай.
                   
  if (Res)
    PrevRates = Rates[0];
    
  return(Res);
}

// Идентификация нового тика
bool IsNewTick_SymbolInfoTick()
{
  static MqlTick PrevTick = {0};
  MqlTick Tick;
  
  const bool Res = ::SymbolInfoTick(_Symbol, Tick) &&
//                   (_R(PrevTick) != Tick); // TypeToBytes.mqh
                   ((PrevTick.time_msc != Tick.time_msc) ||
                    (PrevTick.bid != Tick.bid) ||
                    (PrevTick.ask != Tick.ask));
                   
  if (Res)
    PrevTick = Tick;
    
  return(Res);
}

// Идентификация нового тика
bool IsNewTick_CopyTicks()
{
  static MqlTick PrevTick = {0};
  MqlTick Tick[1];
  
  const bool Res = (::CopyTicks(_Symbol, Tick, COPY_TICKS_ALL, 0, 1) == 1) &&
//                   (_R(PrevTick) != Tick[0]); // TypeToBytes.mqh
                   ((PrevTick.time_msc != Tick[0].time_msc) ||
                    (PrevTick.bid != Tick[0].bid) ||
                    (PrevTick.ask != Tick[0].ask));
                   
  if (Res)
    PrevTick = Tick[0];
    
  return(Res);
}

#define  PRINT(A)            \
  if (!A)                   \
    Print(#A + " = false");


void OnTick()
{
  PRINT(IsNewTick_CopyTicks());      // true
  PRINT(IsNewTick_SymbolInfoTick()); // true
  PRINT(IsNewTick_CopyRates())       // false
}

Es mejor no identificar una nueva garrapata a través de las barras.

 
Quedó claro que CopyTicks puede ir por detrás de SymbolInfoTick.
// Замер длительности синхронизации CopyTicks и SymbolInfoTick.

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

bool IsSynch()
{
  MqlTick Tick;
  MqlTick Ticks[1];
  
  return(SymbolInfoTick(_Symbol, Tick) && (CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 1) == 1) && (_R(Tick) == Ticks[0]));
}

ulong WaitSynch( int &Count )
{
  while (!IsStopped() && IsSynch())
    Sleep(0);
    
  const ulong StartTime = GetMicrosecondCount();
  Count = 0;
  
  while (!IsStopped() && !IsSynch())
    Count++;
    
  return(GetMicrosecondCount() - StartTime);
}

void OnTick()
{
  int Count;
  const uint StartTime = GetTickCount();

  while (GetTickCount() - StartTime < 10000)
    Print("Cинхронизация CopyTicks и SymbolInfoTick длилась " + (string)(WaitSynch(Count) / 1000)  + " ms., число проверок = " + (string)Count);
}


Resultado(inAmount = 15).

2020.10.20 00:32:46.316 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 163 ms., число попыток = 391432
2020.10.20 00:32:46.894 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 221 ms., число попыток = 526533
2020.10.20 00:32:50.839 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 69 ms., число попыток = 112339
2020.10.20 00:32:50.839 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 385 ms., число попыток = 837204
2020.10.20 00:32:51.958 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 74 ms., число попыток = 166407
2020.10.20 00:32:52.044 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 80 ms., число попыток = 180256
2020.10.20 00:32:52.797 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 737 ms., число попыток = 1469883
2020.10.20 00:33:04.229 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 8550 ms., число попыток = 14608891
2020.10.20 00:33:04.319 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 159 ms., число попыток = 150630
2020.10.20 00:33:04.324 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 85 ms., число попыток = 78591
2020.10.20 00:33:07.340 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 2947 ms., число попыток = 4899320
2020.10.20 00:33:08.076 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 727 ms., число попыток = 1209371
2020.10.20 00:33:08.138 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 55 ms., число попыток = 73155
2020.10.20 00:33:14.233 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 107 ms., число попыток = 149697
2020.10.20 00:33:15.985 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 190 ms., число попыток = 230501
2020.10.20 00:33:16.114 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 208 ms., число попыток = 275639
2020.10.20 00:33:41.328 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 9457 ms., число попыток = 14426849
2020.10.20 00:33:46.000 Test9 (GBPCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 53622 ms., число попыток = 109127013
2020.10.20 00:33:47.936 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1302 ms., число попыток = 3104323
2020.10.20 00:33:55.715 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 59 ms., число попыток = 87263
2020.10.20 00:33:55.776 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 88 ms., число попыток = 125641
2020.10.20 00:33:55.869 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 86 ms., число попыток = 140282
2020.10.20 00:33:55.974 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 95 ms., число попыток = 91802
2020.10.20 00:33:56.004 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 125 ms., число попыток = 127590
2020.10.20 00:33:56.202 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 214 ms., число попыток = 311277
2020.10.20 00:34:40.522 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 31 ms., число попыток = 48189
2020.10.20 00:34:40.672 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 69 ms., число попыток = 99619
2020.10.20 00:34:41.094 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 412 ms., число попыток = 613382
2020.10.20 00:34:41.864 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 768 ms., число попыток = 1136798
2020.10.20 00:34:46.035 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 2012 ms., число попыток = 2955715
2020.10.20 00:34:46.124 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 79 ms., число попыток = 109796
2020.10.20 00:34:46.239 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 98 ms., число попыток = 152433
2020.10.20 00:34:47.261 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1009 ms., число попыток = 1300923
2020.10.20 00:34:47.337 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 73 ms., число попыток = 66414
2020.10.20 00:34:47.850 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 885 ms., число попыток = 832072
2020.10.20 00:34:48.383 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1040 ms., число попыток = 1239140
2020.10.20 00:34:49.093 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 46 ms., число попыток = 43232
2020.10.20 00:34:49.839 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1445 ms., число попыток = 2065046
2020.10.20 00:34:51.474 Test9 (GBPCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 55801 ms., число попыток = 119517920
2020.10.20 00:34:51.755 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1498 ms., число попыток = 1625714
2020.10.20 00:34:52.269 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 403 ms., число попыток = 693015
2020.10.20 00:34:59.175 Test9 (AUDCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 9413 ms., число попыток = 16211601
2020.10.20 00:35:00.398 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 6302 ms., число попыток = 11626079
2020.10.20 00:35:05.587 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 3645 ms., число попыток = 8637511
2020.10.20 00:35:07.247 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 133 ms., число попыток = 205326
2020.10.20 00:35:09.033 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 3427 ms., число попыток = 8060967

La desincronización puede durar hasta un minuto. Hay un error en alguna parte.

 

La razón del frenado de SymbolInfoTick parece ser el manejo paralelo.

// Демонстрация тормозов SymbolInfoTick
#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

void OnTick()
{
  const uint StartTime = GetTickCount();

  while (!IsStopped() && (GetTickCount() - StartTime < 10000))
  {
    _B(SymbolInfoInteger(_Symbol, SYMBOL_TIME_MSC), 100000);
    
//    Sleep(0); // Специально убрал.
  }
}


Resultado (inAmount = 15).

2020.10.20 01:01:30.517 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 105941 mcs.
2020.10.20 01:01:37.596 Test9 (USDCAD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 103045 mcs.
2020.10.20 01:01:38.968 Test9 (EURCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 103305 mcs.
2020.10.20 01:01:41.307 Test9 (EURUSD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 106121 mcs.
2020.10.20 01:01:42.573 Test9 (USDCAD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 128241 mcs.
2020.10.20 01:01:45.175 Test9 (GBPCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 120367 mcs.
2020.10.20 01:01:46.394 Test9 (EURCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 104458 mcs.
2020.10.20 01:01:57.832 Test9 (GBPCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 125348 mcs.

> 100 ms para la ejecución de SymbolInfoTick. Está claro que el código se dispara solo. Pero muestra la razón por la que se ralentiza en los EAs habituales.