O que está acontecendo com meu BOTzinho ?

 

Salve, Salve, rapaziada!

Criei um bot vencedor, e no backtest as entradas e saídas ele faz sem problemas,

mas de repente, não mais que de repente, ele começa a fazer entradas de compra e venda (o contrário também é verdadeiro) dezenas de vezes na mesma vela.

Já verifiquei a logica e está OK, acredito que se estivesse errada as entradas anteriores também ocorreria essa anomalia.

Vide imagem para maior esclarecimento (WDO$N - M1). Poderia me ajudar nessa demanda?


Anomalia aocorrida no descaque em amarelo.


Obrigado

 
Anderson De Assis:

Salve, Salve, rapaziada!

Criei um bot vencedor, e no backtest as entradas e saídas ele faz sem problemas,

mas de repente, não mais que de repente, ele começa a fazer entradas de compra e venda (o contrário também é verdadeiro) dezenas de vezes na mesma vela.

Já verifiquei a logica e está OK, acredito que se estivesse errada as entradas anteriores também ocorreria essa anomalia.

Vide imagem para maior esclarecimento (WDO$N - M1). Poderia me ajudar nessa demanda?




Obrigado

Possivelmente, voce tem um erro na checagem de doubles/floats que deve estar validando com "==" ao inves de definir um um limite de exatidao. Isso ocorre que quando tu cadastra que o preco foi feito no valor X digamos 5248, o que voce recebe seria algo como "5248.000003" e quando voce passa pelo valor novamente por alma do destino o que vem seria "5248.000001". Sendo assim, nao igual abre a ordem novamente...

Se quiser ajuda mesmo, tem que mostrar o codigo para gente lhe ajudar mostrando onde sua checagem esta falhando.

 
Ricardo Rodrigues Lucca #:

Possivelmente, voce tem um erro na checagem de doubles/floats que deve estar validando com "==" ao inves de definir um um limite de exatidao. Isso ocorre que quando tu cadastra que o preco foi feito no valor X digamos 5248, o que voce recebe seria algo como "5248.000003" e quando voce passa pelo valor novamente por alma do destino o que vem seria "5248.000001". Sendo assim, nao igual abre a ordem novamente...

Se quiser ajuda mesmo, tem que mostrar o codigo para gente lhe ajudar mostrando onde sua checagem esta falhando.

Obrigado. Abaixo trecho do código.


enum ENUM_POSITION  {Zerado=0,Comprado,Vendido};
enum ENUM_ENTRY_ONLY
  {
   Compra = 0, // Compra
   Venda,      // Venda
   CompraVenda // Compra e venda
  };

enum ENUM_NO_YES
  {
   Nao=1,  // Não
   Sim     // Sim
  };


input ENUM_NO_YES                inpVirarMao=Sim;                          // Virada de mão (reverter com sinal)

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
.
.
.
position = CheckPosition();

ENUM_SIGNAL signal = GetSignal();


if(position == Zerado)
  {

// sinal de compra
   if(signal == Comprar && (inpSoOperar ==  Compra || inpSoOperar == CompraVenda))
      m_trade.Buy(inpLote,m_symbol.Name(),m_symbol.Ask(),CalculateStopLoss(ORDER_TYPE_BUY),CalculateTakeProfit(ORDER_TYPE_BUY),"Compra a mercado.");

// sinal de venda
   if(signal == Vender && (inpSoOperar ==  Venda || inpSoOperar == CompraVenda))
      m_trade.Sell(inpLote,m_symbol.Name(),m_symbol.Bid(),CalculateStopLoss(ORDER_TYPE_SELL),CalculateTakeProfit(ORDER_TYPE_SELL),"Venda a mercado.");

  }
else // se posicionado ==============
  {

   if(position == Comprado)
      if(signal == Vender && (inpSoOperar ==  Venda || inpSoOperar == CompraVenda))
         m_trade.Sell(inpLote*inpVirarMao,m_symbol.Name(),m_symbol.Bid(),CalculateStopLoss(ORDER_TYPE_SELL),CalculateTakeProfit(ORDER_TYPE_SELL),"Venda virada.");

   if(position == Vendido)
      if(signal == Comprar && (inpSoOperar ==  Compra || inpSoOperar == CompraVenda || entryByAverageBuy))
         m_trade.Buy(inpLote*inpVirarMao,m_symbol.Name(),m_symbol.Ask(),CalculateStopLoss(ORDER_TYPE_BUY),CalculateTakeProfit(ORDER_TYPE_BUY),"Compra virada.");

  }

.
.
.

}



ENUM_POSITION CheckPosition()
  {

   ENUM_POSITION retorno = Zerado;

   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i) > 0)
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==inpNumeroMagico)
           {
            if(m_position.PositionType()==POSITION_TYPE_BUY)
               retorno = Comprado;

            if(m_position.PositionType()==POSITION_TYPE_SELL)
               retorno = Vendido;
           }

   return retorno;

  }
 
Anderson De Assis #:

Obrigado. Abaixo trecho do código.


Nesse trecho acredito que nao tem nada que chamou muito a atencao. Mas mesmo assim vou comentar.

O else do position, testa os diferentes valores possiveis (comprado/vendido). Mas, nao vi ele testar se a virada de mao esta permitida.

O CheckPosition parece estar certo, entretanto nao sei se a conta eh hedging ou netting. Se a conta for netting, esta certo. Se ela for hedging, voce tem um problema porque esta pegando uma posicao arbitraria (que seria a mais antiga, primeira position) e retornando o tipo dela. Entretanto voce tem outras posicoes que podem ser opostas ou na mesma direcao. Alem disso, para virar a mao na hedging nao eh dessa forma.

O GetSignal pode ser problema, mas nao foi mostrado....

 

OnTick é chamado inúmeras vezes antes de CheckPosition retornar valor de posicionado, então uma nova entrada é efetuada. Resolvi colocando um Sleep(500) em OnTransactionTrade().

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {


   Sleep(500);

}
 
Anderson De Assis #:

OnTick é chamado inúmeras vezes antes de CheckPosition retornar valor de posicionado, então uma nova entrada é efetuada. Resolvi colocando um Sleep(500) em OnTransactionTrade().

Entendi, tem umas corretoras que demoram muito para abrir as ordens mesmo. Mas tu pode pensar em ao inves de ter o sleep ali, mover para executar o codigo do robo a cada segundo via OnTimer.

Outra coisa que tinha entendido eh que o problema era no teste historico! E nao em conta demo, entao isso tinha excluido.

 
Anderson De Assis:

Salve, Salve, rapaziada!

Criei um bot vencedor, e no backtest as entradas e saídas ele faz sem problemas,

mas de repente, não mais que de repente, ele começa a fazer entradas de compra e venda (o contrário também é verdadeiro) dezenas de vezes na mesma vela.

Já verifiquei a logica e está OK, acredito que se estivesse errada as entradas anteriores também ocorreria essa anomalia.

Vide imagem para maior esclarecimento (WDO$N - M1). Poderia me ajudar nessa demanda?




Obrigado

Observe o calculo do seu stop/profit, caso ele esteja curto, independe para ele esta na mesma vela ou não, afinal de contas, caso não trate o sinal de entrada que o levou a adquirir uma nova posição ele o persistirá fazendo novas compras/vendas enquanto estiver recebendo-o.

Caso de fato não deseje que ele abra novas posições em uma vela que ele já realizou uma operação, deve utilizar uma regra para evitar o minuto em que o trade anterior foi realizado

Sugestão:

Pegue o valor do último minuto quando realizar uma operação, através de uma struct mql datetime por exemplo, armazene este valor e, determine como regra no seu if que ele não deverá adquirir uma nova posição caso os minutos sejam iguais.

Agora, se a questão não é a vela e sim o preço, aí a conversa é bem mais complexa, dada a variedade de circunstâncias, mas sem dúvida a lógica acima basta para resolver seu problema atual.

Razão: