MT5 e velocidade em ação

 

O MT5 é uma plataforma ágil. Mas há estrangulamentos que negam todos os esforços de comércio rápido.

Gostaria de recolher os problemas aqui, discuti-los e resolvê-los em algum lugar com meus próprios esforços, em algum lugar com a ajuda dos Desenvolvedores.

 

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.

void OnTick()
{
  MqlTick Tick;

  if (SymbolInfo(_Symbol, Tick) && HistorySelect(Tick.time, INT_MAX)) // Взяли история торгов со времени текущего тика.
    // Проверяем актуальность тика через сравнение Tick.time_msc и DEAL_TIME_MSC.
}


Infelizmente, tal chamada da HistorySelect leva 5-30 milissegundos (eu mesmo a medi no ReleaseEX5). Quando o Expert Advisor faz várias atualizações desse tipo no OnTick (de uma boa maneira, isso deve ser feito após cada 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.


Por favor, pense em introduzir tais funções para trabalhar com a história.

HistoryDealsSelect( const int Index, const int Count = WHOLE_ARRAY );  // Из внутренней таблицы сделок взять сделки, начиная с заданного индекса в таблице.
HistoryOrdersSelect( const int Index, const int Count = WHOLE_ARRAY ); // Из внутренней таблицы ордеров взять ордера, начиная с заданного индекса в таблице.

Eles fechariam completamente os freios HistorySelect. Porque isso resolveria o problema de obter os últimos negócios muito baratos. Neste momento, é um tormento na execução de combate.


Nem sempre é possível controlar os últimos negócios via OnTradeTransaction. Portanto, é urgente um trabalho rápido com a história.

 

Acesso aos eventos ChartEvent e TradeTransaction.


Uma idéia e uma das possíveis implementações foi sugerida. Portanto, estou apenas copiando aqui.

Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais

Erros, bugs, perguntas

Sergey Dzyublik, 2020.05.20 00:47

Sugestão para os desenvolvedores.
Por favor, considere adicionar na MQL uma função que permita aos usuários chamarem independentemente o processamento de "mensagens" acumuladas no OnChartEvent a partir de código personalizado.
1) Isso permitiria chamar o OnChartEvent de manipulação entre iterações de um cálculo demorado, tornando a GUI do usuário pelo menos um pouco responsiva sem construir uma horta de: pool de tarefas, transferência de dados, sincronização de estados, economia de contexto e restauração...
2) Isto permitiria o uso do OnChartEvent em scripts.

Obrigado.

Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais

Bichos, insetos, perguntas

Sergey Dzyublik, 2020.05.20 13:39

Não exatamente, eu preferiria chamar esta função de HandleNextEvent, uma possível assinatura:

bool HandleNextEvent (ENUM_EVENT_TYPE);


Quando chamado, semelhante ao GetNextEvent, ele verifica se o ENUM_EVENT_TYPE especificado está presente na fila,
e se este evento estiver presente, ele passa automaticamente o controle para o código do usuário do manipulador correspondente (OnChartEvent, OnTrade, OnTradeTransaction, ... (graçasao fxsaber pela adição)).
Retorna verdadeiro se houve um evento na fila, caso contrário, retorna falso.


Caso de uso possível:

//....
for(int i = 0; i < 10^6; ++i){
   // .... Data Calculations

   if((i % 10^3) == 0){
       while(HandleNextEvent(EVENT_TYPE_ALL));
   }
}
//....

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Erros, Erros, Perguntas

Sergey Dzyublik, 2020.05.20 14:38

2) É isso mesmo. Se eu estiver interessado em processar um determinado evento, não todos os eventos do sistema, seria bom poder processar apenas este tipo de eventos, deixando o processamento de outros eventos no modo usual.
3) Se o HandleNextEvent for chamado novamente durante o processamento - chamada e processo. A única coisa que pode acontecer é o transbordo de pilha, mas isto é problema do usuário e do código, não do desenvolvedor.
4) Os eventos que não se enquadram no filtro permanecem na mesma seqüência e serão chamados quando o usuário devolver o controle ao sistema, como de costume.


Agora temos que fazer muletas para chegar aos mesmos eventos da TradeTransaction dentro do código de execução.

Os consultores especialistas realmente precisam desta característica para a aplicação em combate.

 
fxsaber:

Nem sempre é possível monitorar as transações recentes através da OnTradeTransaction. Portanto, um trabalho rápido com o histórico é relevante.

Por favor, dê um exemplo quando não é possível controlar?

 
prostotrader:

Por favor, me dê um exemplo quando não há controle?

Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais

Peculiaridades de mql5, dicas e truques

fxsaber, 2020.04.23 19:51

As setas de abrir/fechar que o MT5 coloca automaticamente em tempo real são baseadas em eventos da TradeTransaction.


Vi apenas que estes eventos (abertura e fechamento de cerca de uma dúzia de posições) não chegaram ao terminal por causa de uma interrupção momentânea da conexão - foi uma coincidência tão grande que eu estava sentado no meu PC e os olhava em primeira mão. Como resultado, não há flechas correspondentes.


E, como já foi dito aqui, você não pode contar com a OnTradeTransaction em EAs de combate. É uma pena que não exista um mecanismo público confiável para lidar com a OrderSendAsync.


E também quando vários OrderSend são colocados dentro do código. Quando um pedido é enviado depende do pedido anterior.

 
fxsaber:

Também ao colocar vários OrderSend dentro do código. Quando um OrderSend depende do OrderSend anterior.

Se houver uma quebra na comunicação, nada será acrescentado à história também!

Eu tenho usadoOrderSendAsync por mais de 5 anos(havia problemas com OrderSend naquela época) + OnTradeTransaction() apenas em modo de combate - sem problemas!

Se houver uma quebra na conexão, ela é descoberta pelo assistente que é atribuído a cada pedido (em FOREX é difícil de fazer porque os nomes dos símbolos não são padronizados).

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
prostotrader:

Se houver uma quebra na comunicação, nada será acrescentado à história também!

Eu tenho usadoOrderSendAsync por mais de 5 anos(havia problemas com OrderSend naquela época) + OnTradeTransaction() apenas em modo de combate - sem problemas!

Você não pode deixar de notar como vem afundando seus dentes na Async+OnTrade há anos. Você faz a atualização de dados através deste mecanismo e tudo mais, não há problema.

Por favor, não diga "você simplesmente não sabe cozinhar" aqui, pelo menos.

 
fxsaber:

Você não pode deixar de notar como você tem insistido na Async+OnTrade há anos. Você também faz atualizações de dados através deste mecanismo e tudo mais, porque não há problema.

Por favor, não reivindique "você simplesmente não sabe cozinhar" pelo menos aqui.

Você está "lutando" por microssegundos e, ao mesmo tempo, está escrevendo toneladas de código, o que também consome tempo,

e 99% das vezes você não precisa dele.

 
Eu os encorajo a falar somente de maneira construtiva.
 
fxsaber:

Acesso aos eventos ChartEvent e TradeTransaction.

Uma idéia e uma das possíveis implementações foi sugerida. Portanto, estou apenas copiando aqui.

Agora, para ter acesso a esses eventos da TradeTransaction dentro do código de execução, temos que fazer muletas.

Você está fazendo muletas em uma direção errada:

Deixar em OnXXX funções somente cópia de eventos (parâmetros) em fila e chamar a principal função OnMain. Mova todos os seus códigos para as funções On2XX duplicadas. 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?

 
A100:

Deixe as funções OnXXX apenas copiando eventos (parâmetros) para a fila e chamando a principal função OnMain. Mova todos os 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-os por sua vez os dados da fila como parâmetros.

Por favor, me dê um código de esquema rudimentar desta idéia. À primeira vista, parece um completo mal-entendido.

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

Razão: