MT5 e velocidade em ação - página 62

 
Rorschach:
Um núcleo em tempo real ajudaria de alguma forma?

Coloque mais núcleos e não empurre a situação para 100% de carga de um único núcleo.

Não acredite em contos de fadas, processadores e agendadores de fios não funcionam da maneira que você imagina.

 
Anton:

Nas últimas construções, a recepção do tick stream não tem efeito, mesmo teoricamente. Praticamente SymbolInfoTick já funciona com cache, mas os cidadãos individuais continuam procurando por um gato preto.

E não está nem 80% no teste. Possui 6 agentes funcionando em 4 núcleos, ou seja, 100% garantido.

A única questão é como o agendador de tarefas de seu sistema está lidando com a situação. Ao mesmo tempo, algumas alegações estão sendo feitas de que a culpa é da implementação do terminal.

Ou seja, uma situação é criada artificialmente quando um computador é sobrecarregado, quando literalmente tudo nele fica mais lento, e então são feitas algumas reivindicações na forma de "Oh, olha, por que o terminal às vezes está atrasado".

Vamos fechar os olhos para o fato de que mesmo em tais condições é "cerca de 0,01%" - para o inferno com os detalhes! Basta dizer que "ninguém se preocupa com a temperatura média hospitalar", "os atrasos causam problemas no comércio" e "queremos o HFT".

Além disso, é claro que queremos HFT em 20 especialistas em uma antiga mesa de escritório ou em uma máquina virtual morta.

PS PositionSelectByTicket() em sua implementação certamente tem acesso a um recurso compartilhado com sincronização de acesso. E se você não selecionar a posição em cada chamada, você está lendo o preço antigo. Foi mais fácil fazer um "instantâneo" através do SymbolInfoDouble.

obrigado

Recebi minha pergunta porque há seis meses atrás, eu estava otimizando meu código e testando a velocidade das funções do sistema, e há seis meses atrás, SymbolInfoDouble era mais lento que SymbolInfoTick

Mas talvez seja verdade o que você está dizendo. Hoje eu estava procurando no Google poucos artigos sobre o cache multi-core (não me interessei por esta informação por muito tempo),

aqui está um pequeno artigohttps://i2hard.ru/publications/25666/

a questão é que os dados só funcionam em ALU a partir do cache L1, que é muito pequeno e se você carregar o processador em velocidade máxima, então realmente - o teste se transformará em um teste do sistema operacional + teste da velocidade do cache do processador (carregamento, previsão de dados L1+L3), mas não no desempenho do código de teste (aplicação)

 

fxsaber, e se você estabelecer uma prioridade baixa para os agentes em tarefas de gerenciamento e uma prioridade alta para o MT5?

Não consigo encontrar um utilitário que bloqueie todos os programas/fios de OS de serem alocados a uma thread específica da CPU, caso contrário seria possível para o MT5 reservar uma thread e bloqueá-la automaticamente de ser usada por outros programas, o que em teoria poderia reduzir os atrasos.

 
Anton:

Nas últimas construções, a recepção do tick stream não tem efeito, mesmo teoricamente. Praticamente, SymbolInfoTick já funciona com cache, mas certos cidadãos continuam procurando um gato preto.

Um determinado cidadão tem o código MQLduplicado de suas calças largas que mostrou que a muleta funciona mais rápido do que a função normal sob as mesmas condições.

Mas você argumenta que sua função é boa, ela só tem limitações quanto às condições de uso.

E não está nem 80% no teste. Existem 6 agentes funcionando em 4 núcleos, ou seja, 100% garantidos.

A única questão é como o agendador de tarefas de seu sistema está lidando com a situação. Ao mesmo tempo, os autores afirmam que a culpa é da implementação do terminal.

Isto é, uma situação é criada artificialmente quando um computador é sobrecarregado até seus limites e tudo fica mais lento nele, e então são feitas algumas reivindicações na forma de "Oh, veja, por que o terminal às vezes está atrasado".

6/8 - nada está atrasado. Navegadores, compilação, depuração, etc. funcionam em paralelo sem qualquer sinal de desfasamento.

Mas agora eu desliguei tudo de propósito, deixando apenas 4/8 Agente. A situação não mudou com sua frenagem funcional.

Emais, é claro, queremos HFT em 20 especialistas em uma mesa de escritório antiga ou em uma máquina virtual morta.

Foi utilizada uma máquina rápida. E apenas 6 gráficos já estavam dando os freios.

PS PositionSelectByTicket() em sua implementação certamente tem acesso a um recurso compartilhado com sincronização de acesso. E se você não selecionar a posição em cada chamada, você lê o preço antigo. Foi mais fácil "instantâneo" via SymbolInfoDouble.

Eu também uso isto.

// Снепшот 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);
}
 

Que tipo de velocidade no desempenho de combate podemos falar quando há problemas no terminal.

O Expert Advisor escaneia todos os instrumentos financeiros e procura por um determinado padrão.

Ela tropeça em um símbolo e fica pendurada!!!

Código de ajuda, eu coloco apenas passos, instrumento financeiro com problema e 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 do trabalho:

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

Eu nunca esperei que o roteiro terminasse de correr.

Enquanto o terminal tiver tais bugs, nenhuma execução de batalha está fora de questão!!!

Era esperado que quando uma segurança entra na revisão do mercado, pelo menos todas as suas propriedades e a data de início da história são puxadas para cima para ela. Se não houver histórico no servidor, então

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

Deve retornar NULL imediatamente, por que o tempo de execução 18446744073475877877138 ?


Talvez eu não saiba de nada, a função CopyXXX também fica pendurada por 16-29 segundos!!!

Não é normal que um corretor tenha 3000-6000 instrumentos financeiros.

 
Vladimir Pastushak:

Talvez eu não saiba o quê, as funções CopyXXX também ficam penduradas por 16-29 segundos!!!

Não é normal que um corretor tenha 3000-6000 instrumentos financeiros.

As barras são más. Portanto, por favor, poste sobre eles em outro tópico.

 
fxsaber:

As barras são más. Portanto, por favor, poste sobre eles em outro tópico.

Talvez você saiba como programar um instrumento financeiro e não ficar pendurado por muito tempo?

 
Vladimir Pastushak:

Talvez você saiba como programar um instrumento financeiro e não ficar pendurado por muito tempo?

Ainda não me deparei com tal tarefa.

 
Aleksey Vyazmikin:

fxsaber, e se você estabelecer uma prioridade baixa para os agentes em tarefas de gerenciamento e uma prioridade alta para o MT5?

Não consigo encontrar um utilitário que bloqueie a alocação de uma thread específica da CPU para todos os programas/ threads de SO, caso contrário seria possível reservar uma thread para MT5 e bloquear automaticamente sua ocupação por outros programas, o que em teoria poderia reduzir os atrasos.

Defina todos os agentes com a menor prioridade.

Não funciona.


ZZZ O número de EAs em execução afeta o resultado.

 

Caros desenvolvedores, poderiam me informar como a MQL_MEMORY_USED é calculada?

Eu fiz um cálculo da memória que todas as variáveis EA ocupam.

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

É inferior a 10%. Se eu entendi corretamente, MQL_MEMORY_USED contém o cache de Histórico e o cache CopyTicks. Mas ainda é muito menos.

Ao mesmo tempo, o Expert Advisor paralelo consome várias vezes menos. Mas o princípio é o mesmo.

Em geral, o que está incluído neste valor?


Salvei um modelo com o Expert Advisor e o apliquei no mesmo gráfico, causando recarga. Já o vi assim.

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

O uso da memória mudou quase por uma ordem de grandeza. É difícil explicar o que isto significa no momento.