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

 
fxsaber:

Por favor, dê um código de diagrama rudimentar para esta idéia. À primeira vista, parece um completo mal-entendido.

Durante a execução da função OnMain, não há como saber o estado da fila real atual. A única solução para fazer isso é um programa de spyware, como indicado no link.

Em sua forma mais simples:

OnXXX( параметры )
{
        запомнить параметры (поместить в очередь)
        OnMain();
}
On2XX( параметры )
{
/*вычисления*/
        поменять приоритет обработки событий (если нужно)
/*вычисления*/
        промежуточный return (если нужно) 
/*вычисления*/
}
void OnMain()
{
        прочитать приоритет обработки событий
        для каждой группы событий
                извлечь параметры из очереди
                OnTradeXXX( параметры )
                удалить событие из очереди
}

Basta mudar a abordagem dos cálculos propriamente ditos (fazer o retorno intermediário com a freqüência que a tarefa exigir). Mas se for difícil, considere no passo 1 que OnMain não existe para você (você move o código principal não em OnMain, mas em On2XX), respectivamente, em OnMain você não precisa aprender nada

 
A100:

As muletas estão sendo feitas na direção errada:

Deixe as funções OnXXX apenas copiando eventos (parâmetros) na fila e chamando a principal função OnMain. Mova todos os seus códigos para duplicar as funções On2XX. E chame estas funções de duplicação On2XX da OnMain na seqüência em que você precisa, passando por sua vez os dados das filas como parâmetros.

Em seguida, execute as medições e mostre o ganho de velocidade, e então você pode sugerir complementar a MQL com a funcionalidade apropriada. Mas por que acrescentar, se você mesmo já fez tudo aqui e agora?

Não é sobre isso que você está escrevendo.
O problema é que a funcionalidade de preenchimento de campos nas variáveis de entrada da função "OntaredeTransaction" não corresponde à descrição dada no Help, para pior:
ou seja, muitos campos não são preenchidos nas chamadas e até mesmo na chamada final de TRADE_TRANSACTION_HISTORY_ADD.
Consequentemente, todos os comerciantes estão agonizando aqui para determinar de alguma forma estes parâmetros em falta no momento da chegada.
Houve muitas discussões aqui, basta fazer uma pesquisa no fórum - a funcionalidade pobre da "OntaredeTransaction" causa despesas adicionais tanto em tempo quanto em "cargas" comerciantes com tempo extra gasto no desenvolvimento de código de trabalho adequado (ou seja, enormes perdas de tempo e ineficácia colossal a nível comunitário).
As respostas atuais dos desenvolvedores como "Se você tem um símbolo de execução do mercado, ele terá valor zero de preço; deve ser assim" (Link).(Link) - isto é UNNORMAL, mais uma vez -
falta de valores exaustivos na última chamada de função leva a muito trabalho extra.

Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
  • 2020.05.18
  • www.mql5.com
В пятницу 22 мая 2020 года будет выпущена обновленная версия платформы MetaTrader 5...
 
fxsaber:

HistóriaSelect.


Esta é uma característica insanamente cara. E infelizmente, nenhuma quantidade de caching pode tornar sua velocidade aceitável agora.


Por exemplo, no campo de batalha EAs, é importante trabalhar com dados reais. Em particular, que os carrapatos do Market Watch e CopyTicks não estejam desatualizados, se possível.

Para fazer isso, não existem mecanismos muito bons, mas mecanismos forçados para verificar a relevância dos dados de preços atuais. Uma parte deste mecanismo é detectar situações em que um comércio sobre um símbolo tenha passado mais tarde do que o último tick. Isto não acontece raramente, portanto é importante saber se o tique atual ainda está atualizado ou não.


Para esta detecção, você precisa poder acessar o histórico dos negócios recentes. É feito usando o HistorySelect da seguinte forma esquemática.


Infelizmente, tal chamada da HistorySelect leva 5-30 milissegundos (eu mesmo a medi no ReleaseEX5). Quando o Expert Advisor faz várias dessas atualizações no OnTick (deve ser feito após qualquer pausa, por exemplo, após cada OrderSend), então tudo se torna insanamente caro/longo. HistorySelect pode comer coletivamente vários segundos em um único OnTick.


Caros desenvolvedores, por que é tão caro? Esta função pode ser executada instantaneamente com a devida implementação.

Você tem provas sobre "tal chamada à HistorySelect dura 5-30 milissegundos"?

Se eu entendi sua idéia corretamente, então o código de teste deve se parecer com isto:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
  }

É assim que funcionam as 100.000 consultas:

100000 HistorySelect = 141.63 ms
 
Anton:

Você tem provas sobre "tal chamada à HistorySelect dura 5-30 milissegundos"?

Se entendi seu ponto de vista corretamente, então o código de teste deve ser parecido com este:

É assim que funcionam 100.000 consultas:

E uma pergunta? Eu não ficaria surpreso se o compilador, ao otimizar, fizesse exatamente isso))))
 
Anton:

Você tem provas sobre "tal chamada à HistorySelect dura 5-30 milissegundos"?

Se entendi seu ponto de vista corretamente, então o código de teste deve ser parecido com este:

É assim que funcionam 100.000 consultas:

Executando seu roteiro.

        100000 HistorySelect = 19493.96 ms


Lançar outro roteiro.

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }
}


HistoryDealsTotal() = 17828
HistoryOrdersTotal() = 22142


Contagem normal de batalha. Não HFT.


A propósito, seu roteiro mostrou que a HistorySelect recalcula tudo a cada vez. E os parâmetros de entrada não mudaram, a tabela do histórico não foi atualizada, outras funções do HistorySelect não foram chamadas.

 
fxsaber:

Executando seu roteiro.

Então, detalhes são necessários.

Meu teste não foi o mais rápido "Intel Xeon E5-2630 v4 @ 2,20GHz", com muitos outros processos em segundo plano.

A conta teste tinha 31315 pedidos em sua história mais ou menos uniformemente desde 2009, incluindo 8 pedidos para hoje.

Talvez, você tivesse algum script ou consultor especializado rodando ao mesmo tempo, causando um carregamento drástico dos bancos de dados do terminal. Experimente-o em um terminal "limpo".

Teste mais informativo:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---   
   ulong start=GetMicrosecondCount();
   int count=100000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   Tick.time=(Tick.time/86400)*86400;
   
   start=GetMicrosecondCount();
   count=1000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   HistorySelect(0, INT_MAX);
   Print("Selected = ",HistoryOrdersTotal());
  }

Três corridas:

2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 141.76 ms
2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.82 ms
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:15.566 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 138.30 ms
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.61 ms
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:18.176 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 142.94 ms
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.57 ms
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:23.498 TestHistorySelect (EURUSD,H1)   Selected = 31315
 
Anton:

Então, detalhes são necessários.

Meu teste não foi o mais rápido "Intel Xeon E5-2630 v4 @ 2.20GHz", com muitos outros processos em segundo plano.

A conta teste tinha 31315 pedidos em sua história mais ou menos uniformemente desde 2009, incluindo 8 pedidos para hoje.

Talvez, você tenha tido algum script ou Expert Advisor rodando ao mesmo tempo, o que carregou drasticamente as bases de dados do terminal. Experimente-o em um terminal "limpo".

Terminal vazio sobre a mesma conta e máquina.

        100000 HistorySelect = 19367.01 ms


Em outras contas e Terminais o mesmo quadro. Configuração.

2020.05.29 13:53:44.766 Terminal        ICMarkets - MetaTrader 5 x64 build 2453 started for International Capital Markets Pty Ltd.
2020.05.29 13:53:44.766 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-2700 K  @ 3.50 GHz, 6 / 15 Gb memory, 4 / 29 Gb disk, IE 11, Admin, GMT+2


Peço aos leitores que dêem seus resultados deste roteiro.

void OnStart()
{
  // https://www.mql5.com/ru/forum/342090/page2#comment_16607997
#define  PRINT(A) Print(#A + " = " + (string)(A))
  
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }

   // https://www.mql5.com/ru/forum/342090/page2#comment_16607922
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
}
 
Anton:

Um teste mais informativo:

Três partidas:

        100000 HistorySelect = 18344.01 ms
        Selected = 0
        1000 HistorySelect = 602.77 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18331.15 ms
        Selected = 0
        1000 HistorySelect = 446.45 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18495.35 ms
        Selected = 0
        1000 HistorySelect = 549.40 ms
        Selected = 1169
        Selected = 22142

Terminal Vazio 2460.


ZS Funciona em conta vazia.

        100000 HistorySelect = 28.30 ms
        Selected = 0
        1000 HistorySelect = 0.28 ms
        Selected = 0
        Selected = 0


A velocidade parece ser fortemente influenciada pelo número de negócios e não pelas ordens.

 
fxsaber:

Terminal Vazio na mesma conta e máquina.


Em outras contas e Terminais, o mesmo padrão. Configuração.


Peço aos leitores que citem seus resultados deste roteiro.

Não prova nada, mas o fato de que a cada nova corrida (em um símbolo diferente), o tempo aumenta - é alarmante...

2020.05.29 13:59:36.625 test1 (USDJPY,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:36.626 test1 (USDJPY,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:36.642 test1 (USDJPY,H1)       100000 HistorySelect = 16.00 ms
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:53.546 test1 (EURUSD,H1)       100000 HistorySelect = 24.36 ms
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:03.669 test1 (USDCHF,H1)       100000 HistorySelect = 29.25 ms
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:15.026 test1 (GBPUSD,H1)       100000 HistorySelect = 31.76 ms
 
Сергей Таболин:

Necessidade de operar em uma conta com um longo histórico comercial.