Como garantir que o EA não fará mais de uma operação no mesmo Candle operando no M1

 

Boa tarde Pessoal, tudo bem?

Pessoal preciso de dicas de como eu poderia garantir que o EA não faça mais de uma entrada de operação no mesmo Candle...

Isto é necessário porque na maioria das vezes que ele faz mais de uma operação no mesmo candle ele toma um loss, por exemplo ele entra baseado nos critérios técnicos sai no gain e entra novamente no mesmo candle por ainda estar satisfazendo os critérios técnicos só que desta vez nem sempre ele sai no gain porque o preço já concluiu seu movimento....

Alguém tem alguma ideia?

Obrigadooooo!!!

 
NandoBueno:

Boa tarde Pessoal, tudo bem?

Pessoal preciso de dicas de como eu poderia garantir que o EA não faça mais de uma entrada de operação no mesmo Candle...

Isto é necessário porque na maioria das vezes que ele faz mais de uma operação no mesmo candle ele toma um loss, por exemplo ele entra baseado nos critérios técnicos sai no gain e entra novamente no mesmo candle por ainda estar satisfazendo os critérios técnicos só que desta vez nem sempre ele sai no gain porque o preço já concluiu seu movimento....

Alguém tem alguma ideia?

Obrigadooooo!!!

Olá, 

uma solução bem simples, usando a classe IsNewBar que está no code base. 

...
#include <IsNewBar.mqh> CIsNewBar       cNbar1, cNbar2, cNbar3, cNbar4;
...
if( FechouPosicao() ) cNbar4.IsNewBar(_Symbol, PERIOD_CURRENT);  // Marca a barra que o trade encerrou
...

if( CriteriosOK() ) // Atende critérios ?
 if (cNbar4.IsNewBar(_Symbol, PERIOD_CURRENT) )  // É nova barra ?
   {
     DoTrade();
   }
 
Rogerio Giannetti Torres #:

Olá, 

uma solução bem simples, usando a classe IsNewBar que está no code base. 

Boa noite Pessoal tudo bem?

Agradeço a dica nobre @Rogerio Giannetti Torres mas porém ela não deu o efeito desejado dentro da estratégia ele acabou deixando de fazer algumas operações que poderia ter feito e saído no Gain inclusive...

A ideia era de que caso ele ainda não tenha feito algum tipo de operação (compra ou venda) naquele candle que ele faça pois este if esta posicionado após a validação que indica se deve ou não fazer a operação.... caso ele já tenha feito uma operação de compra ou venda neste candle que ele não faça uma segunda mesmo que ele seja contrária a que ele já fez....

Alguma ideia de como eu poderia fazer  ????


Implementei da seguinte forma:

   double iClose1[1];

//---- declaration of static variables

   static bool Recount1=true,Recount2=true;

   static CIsNewBar NB1;    


Posisionei este IF depois da validação da regra ou seja pré compra ou venda....


           if(NB1.IsNewBar(Symbol(),_Period) || Recount1) // checking for a new bar

             {

             Recount1=false;

             //--- copy newly appeared data in the arrays

             if(CopyClose(Symbol(),_Period,0,1,iClose1)<=0) {Recount1=true; return;}

             /* Here is a trading signal 1 receiving block code */

           Print("Temos uma Nova Barra");                               

           VendaAMercado();


Obrigado.... abraço.

 
NandoBueno #:

Boa noite Pessoal tudo bem?

Agradeço a dica nobre @Rogerio Giannetti Torres mas porém ela não deu o efeito desejado dentro da estratégia ele acabou deixando de fazer algumas operações que poderia ter feito e saído no Gain inclusive...


Entendo,

bom vai tentando aí, uma hora você acerta.

 
NandoBueno:

. . .


Boa tarde!!


Pra esse caso em que o sinal pode ocorrer a qualquer momento (e não apenas na abertura de nova barra), uma forma bem simples de saber se já foi aberta posição na barra atual seria armazenando iTime(0) sempre que uma posição for aberta, e verificando essa informação antes de abrir nova posição...

//--- Global
   datetime open_time = 0;

   . . .

//--- Open position
   if(open_time != iTime(_Symbol, PERIOD_CURRENT, 0))
     {
      if(!m_trade.Buy(Lot, _Symbol, ASK, SL, TP, COMMENT))
        {
         Print(m_trade.ResultRetcode(), " ", m_trade.ResultRetcodeDescription());
         return;
        }
      open_time = iTime(_Symbol, PERIOD_CURRENT, 0);
     }


Acho que essa solução deve funcionar se o EA não for encerrado e reiniciado durante a execução da mesma barra... Para um maior controle (independente de encerramento/reinício do EA), verifique o horário de abertura da última posição no histórico de operações (por exemplo).


. . .

 
Vinicius de Oliveira #:


Boa tarde!!


Pra esse caso em que o sinal pode ocorrer a qualquer momento (e não apenas na abertura de nova barra), uma forma bem simples de saber se já foi aberta posição na barra atual seria armazenando iTime(0) sempre que uma posição for aberta, e verificando essa informação antes de abrir nova posição...


Acho que essa solução deve funcionar se o EA não for encerrado e reiniciado durante a execução da mesma barra... Para um maior controle (independente de encerramento/reinício do EA), verifique o horário de abertura da última posição no histórico de operações (por exemplo).


. . .

Boa noite @Vinicius de Oliveira tudo bem?


Implementei a tua ideia que achei muito boa só porém ele continua fazendo duas operações no mesmo candle, ele faz a analise recebe o sinal verde para fazer a operação, faz a operação, coloca o gain no bolso só que ai ele entra de novo e faz outra operação se tocar novamente no ponto de entrada e ai ele leva stop na maioria das vezes porque o preço já deu o alvo...


Eu fiz a lógica da seguinte forma será que fiz algo errado ???

       


// Aqui fica a lógica que determina o gatilho se ela for satisfeita ai entra no if abaixo......

if(open_time != iTime(_Symbol, PERIOD_CURRENT, 0))
       {         
           desenhaLinhaVertical("Amarelo",velas[1].time,clrYellow);                   
           VendaAMercado();
           Print("Vendido"   , NormalizeDouble(tick.bid,_Digits)   , "Vela2....." ,  velas[2].high);
           return;
        }
           open_time = iTime(_Symbol, PERIOD_CURRENT, 0);  
          }
       
          }
        else
          {
           Print("Sem venda prevista");
          }
// VendaAMercado() é uma função encarregada de enviar a ordem de venda a mercado...

  Agradeço toda a ajuda este problema esta me tirando o sono...hehehe


Forte abraço.... 

 
NandoBueno #:

Boa noite @Vinicius de Oliveira tudo bem?


Implementei a tua ideia que achei muito boa só porém ele continua fazendo duas operações no mesmo candle, ele faz a analise recebe o sinal verde para fazer a operação, faz a operação, coloca o gain no bolso só que ai ele entra de novo e faz outra operação se tocar novamente no ponto de entrada e ai ele leva stop na maioria das vezes porque o preço já deu o alvo...


Eu fiz a lógica da seguinte forma será que fiz algo errado ???

  Agradeço toda a ajuda este problema esta me tirando o sono...hehehe


Forte abraço.... 


Boa noite, Nando!!


Tente o seguinte:

   if(open_time != iTime(_Symbol, PERIOD_CURRENT, 0))
     {
      desenhaLinhaVertical("Amarelo",velas[1].time,clrYellow);
      VendaAMercado();
      Print("Vendido", NormalizeDouble(tick.bid,_Digits), "Vela2.....",  velas[2].high);
      open_time = iTime(_Symbol, PERIOD_CURRENT, 0);
     }
   else
     {
      Print("Sem venda prevista");
     }


... Mas pra ficar melhor, seria bom se a função VendaAMercado() retornasse true/false (por exemplo) para a abertura da posição, e a variável open_time seria atualizada somente se, realmente, a posição fosse aberta:

   if(open_time != iTime(_Symbol, PERIOD_CURRENT, 0))
     {
      if(!VendaAMercado())
        {
         Print("Erro ao abrir posição...");
         return;
        }
      desenhaLinhaVertical("Amarelo",velas[1].time,clrYellow);
      Print("Vendido", NormalizeDouble(tick.bid,_Digits), "Vela2.....",  velas[2].high);
      open_time = iTime(_Symbol, PERIOD_CURRENT, 0);
     }
   else
     {
      Print("Sem venda prevista");
     }


... Outra opção seria atualizar a variável open_time dentro da função VendaAMercado (se posição aberta sem erros, atualiza; se não, não atualiza)...

 
Vinicius de Oliveira #:


Boa noite, Nando!!


Tente o seguinte:


... Mas pra ficar melhor, seria bom se a função VendaAMercado() retornasse true/false (por exemplo) para a abertura da posição, e a variável open_time seria atualizada somente se, realmente, a posição fosse aberta:


... Outra opção seria atualizar a variável open_time dentro da função VendaAMercado (se posição aberta sem erros, atualiza; se não, não atualiza)...

Bom dia, Vinicius tudo certo por ai?

Fiz as implementações e ele continua fazendo duas operações por candle em alguns momentos....

Vou colocar abaixo como esta construído... para ver se alguém identifica alguma falha.....

Compra: (tudo isso esta dentro da OnTick())

     // Regra para ativar a compra
     if( Comprar == true 
         && GatilhoC == true 
         && PositionSelect(_Symbol)==false 
         && open_time != iTime(_Symbol, PERIOD_CURRENT, 0))
       {
         Print("Open Time..." , open_time,  "Candle...", velas[0].time);         
         desenhaLinhaVertical("Azul",velas[1].time,clrBlue);
         CompraAMercado();
         Print("Comprado   "    , NormalizeDouble(tick.ask,_Digits)   , "Vela2...." , velas[2].low  );     
             
        }
      else
        {       
         Print("Sem compra prevista");
        }

Função CompraAMercado():

// COMPRA A MERCADO
void CompraAMercado() // bser na documentação ordem das variaveis!!!
  {
   MqlTradeRequest   requisicao;    // requisição
   MqlTradeResult    resposta;      // resposta
   bool Comprado = false;
     
   ZeroMemory(requisicao);
   ZeroMemory(resposta);
   
   //--- Cacacterísticas da ordem de Compra
   requisicao.action       = TRADE_ACTION_DEAL;                                // Executa ordem a mercado
   requisicao.magic        = magic_number;                                     // Nº mágico da ordem
   requisicao.symbol       = _Symbol;                                          // Simbolo do ativo
   requisicao.volume       = num_lots;                                         // Nº de Lotes
   requisicao.price        = NormalizeDouble(tick.ask,_Digits);                // Preço para a compra tick.ask original
   requisicao.sl           = NormalizeDouble(tick.ask - SL*_Point,_Digits);    // Preço Stop Loss
   requisicao.tp           = NormalizeDouble(tick.ask + TK*_Point,_Digits);    // Alvo de Ganho - Take Profit
   requisicao.deviation    = 0;                                                // Desvio Permitido do preço
   requisicao.type         = ORDER_TYPE_BUY;                                   // Tipo da Ordem
   requisicao.type_filling = ORDER_FILLING_FOK;                                // Tipo deo Preenchimento da ordem
   
   //---
   if(PositionSelect(_Symbol)==false)
   {
   OrderSend(requisicao,resposta);   
   }
   //---
   if(resposta.retcode == 10008 || resposta.retcode == 10009)
     {
      Print("Ordem de Compra executada com sucesso!");
      open_time = iTime(_Symbol, PERIOD_CURRENT, 0);
      
     }
   else
     {
       Print("Erro ao enviar Ordem Compra. Erro = ", GetLastError());
       ResetLastError();
     }
  }

Obrigado pelo apoio...abraço. 

 
NandoBueno #:

Bom dia, Vinicius tudo certo por ai?

Fiz as implementações e ele continua fazendo duas operações por candle em alguns momentos....

Vou colocar abaixo como esta construído... para ver se alguém identifica alguma falha.....

Compra: (tudo isso esta dentro da OnTick())

Função CompraAMercado():

Obrigado pelo apoio...abraço. 


Bom dia, Nando!!


Eu sei que você está utilizando ali o ORDER_FILLING_FOK, mas só pra tirar a minha dúvida, teste também o código de retorno  TRADE_RETCODE_DONE_PARTIAL (10010):

//---
   if(resposta.retcode == 10008 || resposta.retcode == 10009 || resposta.retcode == 10010)
     {
      Print("Ordem de Compra executada com sucesso!");
      open_time = iTime(_Symbol, PERIOD_CURRENT, 0);
     }


Lembre-se de fazer as mesmas atualizações na função VendaAMercado()...



EDIT.: Amadureça também a ideia de começar a utilizar a classe de negociação CTrade. Facilita bastante e reduz a possibilidade de falhas/erros...


. . .

Documentação sobre MQL5: Biblioteca Padrão / Classes de negociação / CTrade
Documentação sobre MQL5: Biblioteca Padrão / Classes de negociação / CTrade
  • www.mql5.com
CTrade - Classes de negociação - Biblioteca Padrão - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
Razão: