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

 
Rorschach:
¿Ayudaría de alguna manera un núcleo en tiempo real?

Poner más núcleos y no llevar la situación al 100% de carga de un solo núcleo.

No creas en cuentos de hadas, los procesadores y el programador de hilos no funcionan como te imaginas.

 
Anton:

En las últimas versiones, la recepción del flujo de garrapatas no tiene ningún efecto, ni siquiera en teoría. Prácticamente SymbolInfoTick ya funciona con caché, pero los ciudadanos individuales siguen buscando un gato negro.

Y ni siquiera es el 80% en la prueba. Tiene 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, los autores afirman que la culpa es de la aplicació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 una "instantánea" a través de SymbolInfoDouble.

gracias

Mi pregunta se debe a que hace seis meses, estaba optimizando mi código y probando la velocidad de las funciones del sistema, y hace seis meses, SymbolInfoDouble era más lento que SymbolInfoTick

Tal vez sea cierto lo que dices. Hoy he estado buscando en Google algunos artículos sobre la caché multinúcleo (hace tiempo que no me interesaba por esta información),

aquí hay un breve artículohttps://i2hard.ru/publications/25666/

la cuestión es que los datos llegan a la ALU sólo desde la caché L1 que es muy pequeña y si se carga el procesador a toda velocidad, entonces realmente - la prueba se convertirá en una prueba del sistema operativo + prueba de la velocidad de la caché del procesador (carga, predicción de datos L1+L3) pero no en la prueba del rendimiento del código (aplicación)

 

fxsaber, ¿que tal si pones una prioridad baja para los agentes en el administrador de tareas y una alta para MT5?

No puedo encontrar una utilidad que bloquee todos los programas/hilos del SO para que no sean asignados a un hilo específico de la CPU, de lo contrario sería posible reservar un hilo para MT5 y bloquearlo automáticamente para que no sea utilizado por otros programas, lo que en teoría podría reducir los lags.

 
Anton:

En las últimas versiones, la recepción del flujo de garrapatas no tiene ningún efecto, ni siquiera en teoría. Prácticamente, SymbolInfoTick ya funciona con caché, pero ciertos ciudadanos siguen buscando un gato negro.

Un ciudadano particular ha conseguidoduplicar el código MQL de sus pantalones anchos que demostró que la muleta funciona más rápido que la función regular en las mismas condiciones.

Pero usted sostiene que su función es buena, sólo que tiene limitaciones en las condiciones de uso.

Y ni siquiera es el 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 hasta sus límites y todo se ralentiza en él, y entonces se hacen algunas reclamaciones en forma de "Oh, mira, por qué el terminal se retrasa a veces".

6/8 - nada se retrasa. Los navegadores, la compilación, la depuración, etc. se ejecutan en paralelo sin ningún tipo de retraso.

Pero ahora he apagado todo a propósito, dejando sólo 4/8 de agente. La situación no ha cambiado con su función de frenado.

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

Se utilizó una máquina rápida. Y sólo 6 gráficos ya estaban dando los frenos.

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

Yo también uso esto.

// Снепшот SymbolInfoTick для текущего символа.
bool SymbolInfoTick( MqlTick &Tick )
{
  static MqlTick PrevTick = {0};
  static ulong PrevTime = 0;
  
  const ulong NewTime = GetMicrosecondCount();
  const bool Res = (NewTime - PrevTime < 1000) || (::SymbolInfoTick(_Symbol, PrevTick) && (bool)(PrevTime = NewTime));
  
  Tick = PrevTick;
  
  return(Res);
}
 

De qué tipo de velocidad en el rendimiento del combate podemos hablar cuando hay problemas en el terminal.

El Asesor Experto escanea todos los instrumentos financieros y busca un patrón determinado.

Se tropieza con un símbolo y ¡¡¡se agarra fuerte!!!

Código de la ayuda, pongo sólo pasos, instrumento financiero con problema y temporizador:

//+------------------------------------------------------------------+ 
//|                                              TestLoadHistory.mq5 | 
//|                        Copyright 2009, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "2009, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.02" 
#property script_show_inputs 
//--- input parameters 
input string          InpLoadedSymbol="RTSCHH1";   // Symbol to be load 
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1;  // Period to be load 
input datetime        InpStartDate=D'2006.01.01'; // Start date 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
   Print("Start load",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"from",InpStartDate); 
//--- 
   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate); 
   switch(res) 
     { 
      case -1 : Print("Unknown symbol ",InpLoadedSymbol);             break; 
      case -2 : Print("Requested bars more than max bars in chart "); break; 
      case -3 : Print("Program was stopped ");                        break; 
      case -4 : Print("Indicator shouldn't load its own data ");      break; 
      case -5 : Print("Load failed ");                                break; 
      case  0 : Print("Loaded OK ");                                  break; 
      case  1 : Print("Loaded previously ");                          break; 
      case  2 : Print("Loaded previously and built ");                break; 
      default : Print("Unknown result "); 
     } 
//--- 
   datetime first_date; 
   SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date); 
   int bars=Bars(InpLoadedSymbol,InpLoadedPeriod); 
   Print("First date ",first_date," - ",bars," bars"); 
//--- 
  } 
//+------------------------------------------------------------------+ 
//|                                                                  | 
//+------------------------------------------------------------------+ 
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date) 
  { 
  Print(" === 1 === ");
   datetime first_date=0; 
   datetime times[100]; 
//--- check symbol & period 
   if(symbol==NULL || symbol=="") symbol=Symbol(); 
   if(period==PERIOD_CURRENT)     period=Period(); 
//--- check if symbol is selected in the MarketWatch 
   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT)) 
     { 
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1); 
      SymbolSelect(symbol,true); 
     } 
     
     ulong time = GetMicrosecondCount();
     Print(" === 2 === ",first_date);
//--- check if data is present 
  bool date = SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
   
   Print(" === 2.1 === ",(time - GetMicrosecondCount()));
   
   if(first_date>0 && first_date<=start_date) return(1); 
//--- don't ask for load of its own data if it is an indicator 

Print(" === 2.2 === ");
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) 
      return(-4); 
//--- second attempt 
Print(" === 2.3 === ");
   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date)) 
     { 
      //--- there is loaded data to build timeseries 
      Print(" === 2.4 === ");
      if(first_date>0) 
        { 
         //--- force timeseries build 
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times); 
         //--- check date 
         Print(" === 2.5 === ");
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(2); 
        } 
     } 
     
     Print(" === 3 === ");
     
//--- max bars in chart from terminal options 
   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); 
//--- load symbol history info 
   datetime first_server_date=0; 
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped()) 
      Sleep(5); 
//--- fix start date for loading 

Print(" === 4 === ");


   if(first_server_date>start_date) start_date=first_server_date; 
   if(first_date>0 && first_date<first_server_date) 
      Print("Warning: first server date ",first_server_date," for ",symbol, 
            " does not match to first series date ",first_date); 
//--- load data step by step 

Print(" === 5 === ");

   int fail_cnt=0; 
   while(!IsStopped()) 
     { 
      //--- wait for timeseries build 
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped()) 
         Sleep(5); 
      //--- ask for built bars 
      int bars=Bars(symbol,period); 
      if(bars>0) 
        { 
         if(bars>=max_bars) return(-2); 
         //--- ask for first date 
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(0); 
        } 
      //--- copying of next part forces data loading 
      int copied=CopyTime(symbol,period,bars,100,times); 
      if(copied>0) 
        { 
         //--- check for data 
         if(times[0]<=start_date)  return(0); 
         if(bars+copied>=max_bars) return(-2); 
         fail_cnt=0; 
        } 
      else 
        { 
         //--- no more than 100 failed attempts 
         fail_cnt++; 
         if(fail_cnt>=100) return(-5); 
         Sleep(10); 
        } 
     } 
     
     Print(" === 6 === ");
//--- stopped 
   return(-3); 
  } 
//+------------------------------------------------------------------+ 
//| Возвращает строкое значение периода                              | 
//+------------------------------------------------------------------+ 
string GetPeriodName(ENUM_TIMEFRAMES period) 
  { 
   if(period==PERIOD_CURRENT) period=Period(); 
//--- 
   switch(period) 
     { 
      case PERIOD_M1:  return("M1"); 
      case PERIOD_M2:  return("M2"); 
      case PERIOD_M3:  return("M3"); 
      case PERIOD_M4:  return("M4"); 
      case PERIOD_M5:  return("M5"); 
      case PERIOD_M6:  return("M6"); 
      case PERIOD_M10: return("M10"); 
      case PERIOD_M12: return("M12"); 
      case PERIOD_M15: return("M15"); 
      case PERIOD_M20: return("M20"); 
      case PERIOD_M30: return("M30"); 
      case PERIOD_H1:  return("H1"); 
      case PERIOD_H2:  return("H2"); 
      case PERIOD_H3:  return("H3"); 
      case PERIOD_H4:  return("H4"); 
      case PERIOD_H6:  return("H6"); 
      case PERIOD_H8:  return("H8"); 
      case PERIOD_H12: return("H12"); 
      case PERIOD_D1:  return("Daily"); 
      case PERIOD_W1:  return("Weekly"); 
      case PERIOD_MN1: return("Monthly"); 
     } 
//--- 
   return("unknown period"); 
  }

Resultado del trabajo:

2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)   Start loadRTSCHH1,H1from2006.01.01 00:00:00
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 1 === 
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 2 === 1970.01.01 00:00:00
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.1 === 18446744073475877138    Время выполнения SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.2 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.3 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 3 === 

Nunca esperé a que el guión terminara de ejecutarse.

Mientras el terminal tenga esos fallos, ¡¡¡no hay ejecución de batalla que valga!!!

Se esperaba que cuando un valor entrara en la revisión del mercado, se sacaran al menos todas sus propiedades y la fecha de inicio del historial. Si no hay historial en el servidor, entonces

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

Debería devolver NULL al instante, ¿por qué el tiempo de ejecución 18446744073475877138 ?


¡¡¡Tal vez no sé algo, la función CopyXXX también se cuelga durante 16-29 segundos!!!

No es normal que un corredor tenga entre 3000 y 6000 instrumentos financieros.

 
Vladimir Pastushak:

¡¡¡Igual no sé qué, las funciones de CopyXXX también se cuelgan entre 16 y 29 segundos!!!

No es normal que un corredor tenga entre 3000 y 6000 instrumentos financieros.

Los bares son malos. Así que, por favor, publica sobre ellos en otro hilo.

 
fxsaber:

Los bares son malos. Así que, por favor, publica sobre ellos en otro hilo.

¿Quizá sepa cómo seleccionar programáticamente un instrumento financiero y no quedarse colgado durante mucho tiempo?

 
Vladimir Pastushak:

¿Quizá sepa cómo seleccionar programáticamente un instrumento financiero y no quedarse colgado durante mucho tiempo?

No me he encontrado con una tarea así.

 
Aleksey Vyazmikin:

fxsaber, ¿que tal si pones una prioridad baja para los agentes en el administrador de tareas y una alta para MT5?

No encuentro una utilidad que bloquee la asignación de un hilo específico de la CPU a todos los programas/hilos del SO, de lo contrario sería posible reservar un hilo para MT5 y bloquear automáticamente su ocupación por otros programas, lo que en teoría podría reducir los lags.

Poner todos los Agentes en la prioridad más baja.

No funciona.


ZZZ El número de EAs en funcionamiento afecta al resultado.

 

Estimados desarrolladores, ¿podrían informarme de cómo se calcula MQL_MEMORY_USED?

Hice un cálculo de la memoria que ocupan todas las variables de EA.

MQL_MEMORY_USED = 60 MB, Virtual = 3.40 MB ( 5.7%)

Es menos del 10%. Si he entendido bien, MQL_MEMORY_USED incluye la caché del historial y la caché de CopyTicks. Pero sigue siendo mucho menos.

Al mismo tiempo, el Asesor Experto paralelo consume varias veces menos. Pero el principio es el mismo.

En general, ¿qué se incluye a este valor?


He guardado una plantilla con Expert Advisor y la he aplicado al mismo gráfico provocando la recarga. Lo he visto así.

MQL_MEMORY_USED = 7 MB, Virtual = 3.40 MB ( 48.6%)

El uso de la memoria ha cambiado en casi un orden de magnitud. Es difícil explicar lo que esto significa en este momento.