Discussão do artigo "WebRequest multi-threaded assíncrono em MQL5"

 

Novo artigo WebRequest multi-threaded assíncrono em MQL5 foi publicado:

Este artigo descreve uma biblioteca que permite aumentar a eficiência ao trabalhar com solicitações HTTP em linguagem MQL5. O WebRequest é iniciado no modo sem bloqueio em threads adicionais usando gráficos e EAs assistentes, compartilhando eventos personalizados e lendo recursos compartilhados. Códigos fonte estão anexados ao artigo.

A implementação de algoritmos de negociação geralmente requer a análise de informações de várias fontes externas, em particular da Internet. A MQL5 fornece a função WebRequest para enviar solicitações HTTP, mas, infelizmente, ela tem uma falha importante. Esta função é síncrona e, portanto, bloqueia EAs durante toda a duração da solicitação. Lembre-se de que, para cada EA no MetaTrader 5, há uma única thread que executa sequencialmente as chamadas das funções API existentes no código e que inicia manipuladores para eventos de entrada (como ticks, alterações do livro de ofertas no BookEvent, temporizador, negócios, eventos gráficos, etc.). Apenas um trecho de código é executado por vez, enquanto os outros aguardam sua vez, até que o trecho atual retorna o controle ao kernel.

Por exemplo, se um EA tiver que processar novos ticks em tempo real e verificar periodicamente notícias econômicas num ou vários sites, é impossível cumprir os dois requisitos sem causar algum prejuízo. Depois que o WebRequest é executado no código, o EA permanece congelado na string com a chamada de função, enquanto os eventos sobre novos ticks são ignorados. Mesmo considerando que depois os ticks perdidos podem ser lidos usando a função CopyTicks, o momento da toma de decisão pode ser perdido. Veja como esta situação é ilustrada usando o diagrama de sequência UML:

Diagrama de sequência de processamento de eventos com um código de bloqueio numa thread

Fig.1 Diagrama de sequência de processamento de eventos com um código de bloqueio numa thread

Autor: Stanislav Korotky

 

Como sempre, forte! Se a biblioteca pudesse ser generalizada, você poderia criar um kit de ferramentas pronto para criar facilmente a assincronia de qualquer função. Ao mesmo tempo, em várias plataformas.

Esse método poderia ser usado para criar OrderSendAsync para MT4, por exemplo.

Obrigado pelo artigo!

 
fxsaber:

Como sempre, forte! Se a biblioteca pudesse ser generalizada, você poderia criar um kit de ferramentas pronto para criar facilmente a assincronia de qualquer função. Ao mesmo tempo, em uma plataforma cruzada.

Usando esse método, você poderia criar o OrderSendAsync para o MT4, por exemplo.

Sim, eu comecei a criar um sistema de gerenciamento de ordens de grupo para o MT4 com comandos de plug-in em mensagens há muito tempo, mas ele não foi concluído. Não verifiquei como os recursos funcionam no MT4, embora, a julgar pela documentação, deva ser como no MT5.

 
Stanislav Korotky:

Não verifiquei como os recursos funcionam no MT4, embora, de acordo com a documentação, deva ser como no MT5.

Sim, tudo é como no MT5. Somente na versão atual do MT4 há um bug que impossibilita a troca

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Bugs, bugs, perguntas

fxsaber, 2018.09.17 18:38

ResourceReadImage no MT4 com um bug tal que é impossível ler o recurso
#property strict

class RESOURCE
{
public:
  const string Name;

  RESOURCE( const string sName = __FILE__ ) : Name("::" + sName )
  {
  }

  ~RESOURCE( void)
  {
    ::ResourceFree(this.Name);
  }

  virtual bool Set( const uint &Data[], const uint Width = 1, const ENUM_COLOR_FORMAT ColorFormat = COLOR_FORMAT_XRGB_NOALPHA ) const
  {
    return(::ResourceCreate(this.Name, Data, Width, (Width == 0) ? ::ArraySize(Data) : ::ArraySize(Data) / Width, 0, 0, Width, ColorFormat));
  }

  int Get( uint &Data[] ) const
  {
    uint Width;
    uint Height;

    return(::ResourceReadImage(this.Name, Data, Width, Height) ? ::ArraySize(Data) : 0);
  }
};

void OnStart()
{
  RESOURCE Resource;
  
  uint DataIn[] = {0};  
  Resource.Set(DataIn);
   
  uint DataOut[];
  Resource.Get(DataOut);
  
  Print(DataOut[0]); // MT5x64 (build 1881) - 0, MT4 (build 1126) - 4278190100 (valores aleatórios)
}


O ResourceSave grava corretamente, mas o ResourceReadImage tem um grande erro. É possível corrigi-lo? Não verifiquei isso no MT5x32....


Talvez esse método ajude a tornar a leitura de recursos correta no MT4. Não o testei.

 

A propósito, você pode dispensar os gráficos completos - OBJ_CHART. Os scripts são carregados neles. E o WebRequest e o OrderSend funcionam lá.

Dei um exemplo de como fazer uma negociação de indicador sem gráficos adicionais.

Assim, você pode usar o iCustom-indicator como um gerenciador, e ele iniciará o WebRequest em seu script para cada WebRequestAsync.

O design deve ser mais simples e mais confiável, pois não haverá janelas adicionais.

 
fxsaber:

A propósito, você pode dispensar os gráficos completos - OBJ_CHART. Os scripts são carregados neles. E o WebRequest e o OrderSend funcionam neles.

Dei um exemplo de como fazer uma negociação de indicador sem gráficos adicionais.

Assim, você pode usar o iCustom-indicator como um gerenciador, e ele executará o WebRequestAsync em seu script para cada WebRequestAsync.

O design deve ser mais simples e mais confiável, pois não haverá janelas adicionais.

Você pode criar um link para esse exemplo?

 
Maxim Kuznetsov:

Posso ter um link para esse exemplo?

Aqui e aqui.


ZY O usuário provavelmente ficará surpreso se o Market Indicator começar a negociar....

 
fxsaber:

Aqui e aqui.


ZY Provavelmente, o usuário ficará surpreso se o Market-indicator começar a negociar...

Nossa, é apenas uma transferência de eventos.... pensei :-)

 
Maxim Kuznetsov:

merda, é apenas um evento.... eu pensei :-)

Não há nenhum evento.

 
fxsaber:

Não há nenhum evento.

É o script que executa as ordens.

E como ele obtém as ordens é outra questão.

 
Maxim Kuznetsov:

o script executa as ordens.

E como ele recebe as ordens é outra questão.

O script não recebe ordens, ele é acionado pelo indicador em qualquer quantidade.