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

 
Entendo que tudo depende do equipamento
 
Alexsandr San:
Eu entendo que depende do equipamento

De jeito nenhum!

2020.05.29 15:08:44.938 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-6850 K  @ 3.60 GHz, 23 / 31 Gb memory, 43 / 226 Gb disk, IE 11, UAC, Admin, GMT+3
 
Alexsandr San:
Acho que isso depende do hardware.

Acho que não ))))

E nem mesmo de um computador ocupado...

 
prostotrader:

De jeito nenhum!

sim! sua máquina e a anterior têm resultados diferentes - então estou errado, não o poder significa

 
Aleksey Mavrin:

O que é o onMain? Como pode haver mais de um evento na fila do onMain se cada evento chama o onMain para lidar com a fila?

OnMain é uma função. Não é um código real, mas um caso especial - uma resposta à alegação "Não há como saber o estado da fila real atualenquanto se executa a função OnMain".É uma abordagem diferente para os cálculos propriamente ditos

 
A100:

OnMain é uma função. Não é o código real, mas um caso especial - uma resposta à alegação "Não há como saber o estado da fila real atualdurante a execução da função OnMain".Esta é uma abordagem diferente para os cálculos em si

Portanto, só por precaução, OnMain...

:) ;)
 
fxsaber:


Em Combat Advisors, eu embrulhei funções em todos os lugares suspeitos para _B(FuncName(...), AlertTime). Aqui está um pequeno trecho do registro das entradas mais recentes.

A coluna de tempo mostra com que freqüência ocorrem os congelamentos.

Você está substituindo conceitos.

Aqui está sua declaração original:

Infelizmente, tal chamada HistorySelect dura de 5 a 30 milissegundos (medido por mim mesmo no Release-EX5). Quando o Expert Advisor faz várias dessas atualizações no OnTick (de uma boa maneira, isso deve ser feito após qualquer pausa). Por exemplo, após cada OrderSend.), então tudo se torna insanamente caro/longo. HistorySelect pode somar até vários segundos em um único OnTick.

Mesmo em seu terminal, o tempo médio de 0,2ms por chamada é mensurável menos do que os valores especificados na declaração original.

Agora você está dizendo que às vezes o tempo de execução de uma função pode ser visivelmente maior do que a média. Esta é uma questão diferente.

Qualquer pedido de HistorySelect() é uma chamada completa para as bases dos terminais sob sincronizadores. Isto é inevitável. Sim, levando em conta a presença de sincronização de acesso, não podemos garantir um tempo muito curto para a execução desta função.

A solução proposta ao adicionar as funções HistoryDealsSelect() e HistoryOrdersSelect() não muda absolutamente nada neste sentido.

O roteiro para verificar o tempo máximo e médio:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---
   ulong start,end,max_time=0,avr_time=0;
   int   count=100000;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last tick time. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   Tick.time=(Tick.time/86400)*86400;
   max_time=0;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one last day HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last day. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   HistorySelect(0, INT_MAX);
   Print("Orders total: ",HistoryOrdersTotal());
  }
2020.05.29 17:22:04.195 TestHistorySelect (EURJPY,H1)   Last tick time. Selected orders: 0; max time: 0.034 ms; avr time: 0.001 ms; 100000 iterations
2020.05.29 17:22:06.771 TestHistorySelect (EURJPY,H1)   Last day. Selected orders: 141; max time: 0.101 ms; avr time: 0.027 ms; 100000 iterations
2020.05.29 17:22:08.039 TestHistorySelect (EURJPY,H1)   Orders total: 31448
 
Anton:

Um roteiro para verificar os tempos máximo e médio:

Não comentarei sua opinião antes de citada. Aqui está o resultado da execução de seu roteiro.

Mais precisamente, eu mal podia esperar para terminar, então mudei o número de iterações de 100K para 1K.

        Last tick time. Selected orders: 0; max time: 3.880 ms; avr time: 1.315 ms; 1000 iterations
        Last day. Selected orders: 2061; max time: 7.131 ms; avr time: 4.309 ms; 1000 iterations
        Orders total: 50113

Isto merece sequer uma nota satisfatória?

Vejam o absurdo da situação. A fim de descobrir estupidamente o número de acordos que precisamos chamar de HistorySelect! Isto, para dizer de forma branda, não é racional.


Eu gasto na melhor das hipóteses dezenas de milissegundos em cada tick apenas por causa da HistorySelect.

 
A100:

Em sua forma mais simples:

Você só precisa mudar sua abordagem dos cálculos propriamente ditos (fazer retornos intermediários quantas vezes for exigido pela tarefa). Mas se for complicado, considere no primeiro estágio que a OnMain está ausente para você (você coloca o código principal não na OnMain, mas na OnTrade2XX), portanto você não precisa aprender nada na OnMain

Obrigado, foi exatamente assim que eu entendi desde o início e é por isso que eu disse que você não o entendeu totalmente. Aqui está um exemplo de um cenário simples.


Você faz um OrderSend. Se uma determinada posição não tiver fechado na marca logo após a OrderSend, você faz outra OrderSend. Tudo isso é lógico, que precisa ser programado. O Async não é utilizado.


Agora a situação que aconteceu com o nosso robô. Você enviou uma OrderSend e enquanto ela está sendo executada, o Limitador acionou e o TP da posição mencionada acima foi executado.


O que é a implementação do robô esquematicamente? Não sei como implementá-lo sem frear o HistorySelect ou a muleta-spy da OnTradeTransaction que dá acesso a todo o histórico de transações em qualquer lugar do código. Se um mecanismo de acesso à fila de eventos fosse implementado, o exemplo acima seria resolvido de forma elementar.


Todos os fortes na MT5, incluindo os desenvolvedores, por favor, mostrem-me como implementar isto( duas linhasem negrito acima) sem complicações (receio até mencionar lógica comercial complexa).

 
A100:

OnMain é uma função. Este não é o código real, mas um caso especial - uma resposta à alegação " Não há como saber o estado da fila real atual durante a execução da função OnMain".Esta é uma abordagem diferente para os cálculos em si

Bem, é, não é mesmo? E era sobre isso que os caras estavam falando. A fim de implementá-la, é necessário alterar a estrutura de execução dos programas MQL, seja a) pelo menos em duas roscas ou b) adicionar um mecanismo para acessar a fila e controlar seu manuseio.

Com a estrutura atual, seu esquema proposto é impossível de ser implementado.

Razão: