Discussão do artigo "Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XXII): classes de negociação - classe básica de negociação, controle de restrições"

 

Novo artigo Biblioteca para criação simples e rápida de programas para MetaTrader (Parte XXII): classes de negociação - classe básica de negociação, controle de restrições foi publicado:

No artigo, começaremos a criar uma classe básica de negociação da biblioteca e dotaremos a primeira versão com uma funcionalidade de verificação de permissões inicial para realizar operações de negociação. Também expandiremos levemente os recursos e o conteúdo da classe básica de negociação.

Para testar o trabalho dos métodos de verificação de restrições de negociação, é preciso criá-las artificialmente.

Por exemplo:

  1. desativamos a Internet (imitar uma quebra na comunicação com o servidor de negociação),
  2. nas configurações do EA, o proibiremos de negociar (pressionamos F7 e, na janela de configurações do EA aberto na guia "Geral", desmarcamos a caixa "Permitir que o EA negocie"),
  3. desabilitamos no terminal a negociação automática (pressionamos o botão "Autotrading")

E tentamos clicar no botão para abrir uma posição no painel de negociação do EA. Como resultado, obtemos uma entrada no log:

2019.09.26 15:07:55.582 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:07:55.582 1. There is no permission to conduct trading operations in the terminal (the "AutoTrading" button is disabled)
2019.09.26 15:07:55.582 2. No connection to the trading server
2019.09.26 15:07:55.582 3. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Removemos as restrições uma a uma.

Ativamos a Internet e ao tentar abrir uma posição, obtemos:

2019.09.26 15:10:36.766 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:10:36.766 1. There is no permission to conduct trading operations in the terminal (the "AutoTrading" button is disabled)
2019.09.26 15:10:36.766 2. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Ativamos no terminal a negociação automática clicando no botão Autotrading e, ao tentar abrir uma posição, obtemos

2019.09.26 15:13:03.424 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:13:03.424 EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Pressionamos F7 e nas configurações do EA, permitiremos que ele negocie. Ao tentar abrir uma posição, obtemos uma posição aberta:

2019.09.26 15:14:32.619 - Position is open: 2019.09.26 11:14:32.711 -
2019.09.26 15:14:32.619 EURUSD Opened 0.10 Buy #455179802 [0.10 Market-order Buy #455179802] at price 1.09441, Magic number 123

As restantes restrições podem ser verificadas no testador ou numa conta demo, criando uma situação em que uma das restrições funciona, por exemplo, uma restrição no número máximo de ordens pendentes na conta.

Autor: Artyom Trishkin

 

Artem, preciso obter as propriedades de uma posição no mql4 depois de abri-la ou ativar uma ordem. Descobri como obter o índice do evento

ENUM_TRADE_EVENT engine.LastTradeEvent()

e, nesse momento, preciso obter as propriedades disponíveis.

Até encontrei o enum, mas como obter... não consigo encontrar nada.

 
Alexey Viktorov:

Artem, preciso obter as propriedades de uma posição no mql4 depois de abri-la ou ativar uma ordem. Descobri como obter o índice do evento

e, nesse momento, preciso obter as propriedades disponíveis.

Até encontrei o enum, mas como obter... não consigo encontrar nada.

Se o último evento for a abertura de uma posição? Precisamos obter a última posição aberta e acessar todas as suas propriedades? Certo?

Se sim, é fácil (sem verificar os resultados da obtenção da lista e do objeto):


 
Obrigado, farei o restante das perguntas bobas em particular para não assustar os transeuntes. ))))))
 

Estou chegando a algum lugar. Obrigado, a biblioteca é muito útil.

Próxima pergunta (não estúpida): temos duas ordens pendentes. Recebemos um evento na ativação de uma delas e, em seguida, a segunda foi ativada.... E não há nenhuma alteração no evento. Como fazer com que o vigia retorne após receber o evento? Tentei

last_event = WRONG_VALUE;
depois de processar o evento, mas obtive um resultado sem sentido...
 
Alexey Viktorov:

Estou chegando a algum lugar. Obrigado, a biblioteca é muito útil.

Próxima pergunta (não estúpida): temos duas ordens pendentes. Recebemos um evento na ativação de uma delas e, em seguida, a segunda foi ativada.... E não há nenhuma alteração no evento. Como fazer com que o vigia retorne após receber o evento? Eu tentei

depois de processar o evento, mas obtive um resultado sem sentido...

Não estou controlando os eventos corretamente. A biblioteca captura todos eles e, em seguida, o EA de teste verifica a diferença entre o evento passado e o atual. E você tem dois eventos idênticos.

Em princípio, depois de enviar um evento, a biblioteca redefine o próprio evento. Tente receber o evento novamente depois de recebê-lo - deve ser gravado na variável que não há evento e, em seguida, o próximo evento deve ser capturado.

Mas há muito tempo escrevi em meus planos que os eventos de negociação devem ser feitos da mesma forma que os eventos de símbolos ou conta - eles apenas retornam um sinalizador de que há um evento. E então, no programa, podemos ver qual é o evento. Tudo já está preparado para isso no Expert Advisor, apenas para os eventos de negociação há um obstáculo na função OnDoEasyEvent() do Expert Advisor, porque o sinalizador ainda não é retornado - não consigo colocá-lo em minhas mãos:

//--- Processamento de eventos comerciais
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      event=EnumToString((ENUM_TRADE_EVENT)ushort(idx));
      int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS);
     }
     
 
Artyom Trishkin:

O controle de eventos está errado aqui. A biblioteca captura todos eles e, em seguida, o EA de teste verifica a diferença entre o evento passado e o atual. E você tem dois eventos idênticos.

Em princípio, depois de enviar um evento, a biblioteca redefine o próprio evento. Tente receber o evento novamente depois de recebê-lo - deve ser gravado na variável que não há evento e, em seguida, o próximo evento deve ser capturado.

Mas há muito tempo escrevi em meus planos que os eventos de negociação devem ser feitos da mesma forma que os eventos de símbolos ou contas - eles apenas retornam um sinalizador de que há um evento. E então, no programa, podemos ver qual é o evento. Tudo já está preparado para isso no Expert Advisor, apenas para os eventos de negociação há um obstáculo na função OnDoEasyEvent() do Expert Advisor, porque o sinalizador ainda não é retornado - não consigo colocá-lo em minhas mãos:

Isso é certo, a manhã é mais sábia à noite.... Se um evento for recebido, no meu caso específico, devemos reagir a ele de alguma forma. Em particular, colocar outra ordem pendente. Isso é o que acontece com o novo evento.

 
Não, afinal, você precisa redefinir o sinalizador de evento.
 
Artyom Trishkin:

O controle de eventos está errado aqui. A biblioteca captura todos eles e, em seguida, o EA de teste verifica a diferença entre o evento passado e o atual. E você tem dois eventos idênticos.

Em princípio, depois de enviar um evento, a biblioteca redefine o próprio evento. Tente receber o evento novamente depois de recebê-lo - deve ser gravado na variável que não há evento e, em seguida, o próximo evento deve ser capturado.

Mas há muito tempo escrevi em meus planos que os eventos de negociação devem ser feitos da mesma forma que os eventos de símbolos ou conta - eles apenas retornam um sinalizador de que há um evento. E então, no programa, podemos ver qual é o evento. Tudo já está preparado para isso no Expert Advisor, apenas para os eventos de negociação há um obstáculo na função OnDoEasyEvent() do Expert Advisor, porque o sinalizador ainda não é retornado - não consigo colocá-lo em minhas mãos:

Mas event é uma variável disponível somente em OnChartEvent, e não é processada no testador.

Quero fazer algo parecido com isso em OnTick():

//--- Se o último evento de negociação foi alterado
 if(engine.LastTradeEvent() != last_event)
  {
   switch(last_event)
    {
     case TRADE_EVENT_PENDING_ORDER_PLASED :
      // chamar a função correspondente
     break;
     case TRADE_EVENT_PENDING_ORDER_REMOVED :
      // chamar a função correspondente
     break;
     case TRADE_EVENT_PENDING_ORDER_ACTIVATED :
      // chamar a função correspondente
     break;
     case TRADE_EVENT_POSITION_OPENED :
      // chamar a função correspondente
     break;
     case TRADE_EVENT_POSITION_CLOSED :
      // chamar a função correspondente
     break;
     
     default :
      break;
    }
 
Alexey Viktorov:

Mas event é uma variável disponível somente em OnChartEvent, e não é processada no testador.

Quero fazer algo parecido com isso em OnTick():

Então, depois de processar o evento - no final do módulo de verificação do tipo de evento, o que você tem na variável last_event? Essa variável deve ser redefinida no Expert Advisor. Em vez de chamar à força o método de redefinição do último evento da biblioteca, a própria biblioteca o chama logo após enviar o evento para o gráfico e gravá-lo na lista de eventos.

 
Alexey Viktorov:

Mas event é uma variável disponível somente em OnChartEvent, e não é processada no testador.

Quero fazer algo parecido com isso em OnTick():

Preste atenção à função de teste do EA OnDoEasyEvent() - ela lida com todos os eventos da biblioteca. E se você quiser processar eventos de negociação com um switch, faça-o lá.