Erro 10016 - robô tentando alterar (desnecessariamente) posição já modificada.

 
   if(PositionSelect(_Symbol))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         trailingStopDown();
        }
      else
         if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
           {
            trailingStopUp();
           }
     }
  }
//---Trailing (se comprado)
void trailingStopDown()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string _symbol = PositionGetSymbol(i);
      if(_symbol==_Symbol)
        {
         double priceOpen=PositionGetDouble(POSITION_PRICE_OPEN);
         ulong _ticket=PositionGetInteger(POSITION_TICKET);
         if(downAtr[1]!=EMPTY_VALUE)
           {
            double newSTL=downAtr[1]-MathMod(downAtr[1],0.5)-10;
            if(trade.PositionModify(_ticket,newSTL,0))
              {
               Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
              }
            else
              {
               Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
              }
           }
        }
     }
  }
//---Trailing (se vendido)
void trailingStopUp()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string _symbol = PositionGetSymbol(i);
      if(_symbol==_Symbol)
        {
         ulong _ticket=PositionGetInteger(POSITION_TICKET);
         if(upAtr[1]!=EMPTY_VALUE)
           {
            double newSTL=upAtr[1]-MathMod(upAtr[1],0.5)+10;
            if(trade.PositionModify(_ticket,newSTL,0))
              {
               Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
               Comment("Dif Stop-Atr = ",MathAbs(newSTL-upAtr[1])-MathMod(MathAbs(newSTL-upAtr[1]),0.5));
              }
            else
              {
               Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
              }
           }
        }
     }
  }

Prezados,

Pesquisei bastante no fórum antes de abrir novo tópico e até encontrei temas semelhantes, mas nada que se encaixasse no meu problema. Sou estudante de MQL e estou a desenvolver um robozinho tosco de teste e aí me deparei com o seguinte problema: O trailing stop acompanha o indicador customizado ATR com uma distância de segurança de 10 pontos de dólar. Até aí tudo perfeito, conforme o trade evolui ele vai embora sem problemas, porém observo no log que o robô está tentando incessantemente modificar posições já modificadas (para o mesmo nível de preço) vindo a ocasionar o erro 10016 (stop inválido). Já criei algumas funções booleanas com for loop para 'avisar' que o trailing já foi ativado e modificar o stop loss somente uma vez, mas ao contrário, o trailing para de funcionar. Segue parte do código para que alguém possa me ajudar a encontrar onde está minha falha, que talvez possam ser muitas. Resumindo, quero que o robô pare de tentar alterar incessantemente, através do trade.PositionModify, a posição desnecessariamente, esperando que o indicador ATR se altere para, aí sim, modificar a posição. De antemão já agradeço pelos bons préstimos e paciência.

 
Daniel D.:

Prezados,

Pesquisei bastante no fórum antes de abrir novo tópico e até encontrei temas semelhantes, mas nada que se encaixasse no meu problema. Sou estudante de MQL e estou a desenvolver um robozinho tosco de teste e aí me deparei com o seguinte problema: O trailing stop acompanha o indicador customizado ATR com uma distância de segurança de 10 pontos de dólar. Até aí tudo perfeito, conforme o trade evolui ele vai embora sem problemas, porém observo no log que o robô está tentando incessantemente modificar posições já modificadas (para o mesmo nível de preço) vindo a ocasionar o erro 10016 (stop inválido). Já criei algumas funções booleanas com for loop para 'avisar' que o trailing já foi ativado e modificar o stop loss somente uma vez, mas ao contrário, o trailing para de funcionar. Segue parte do código para que alguém possa me ajudar a encontrar onde está minha falha, que talvez possam ser muitas. Resumindo, quero que o robô pare de tentar alterar incessantemente, através do trade.PositionModify, a posição desnecessariamente, esperando que o indicador ATR se altere para, aí sim, modificar a posição. De antemão já agradeço pelos bons préstimos e paciência.

Poste o código inteiro... ninguém consegue adivinhar o começo de tudo, inclusive do problema...

Lembre-se sempre que em mercados de alta volatilidade você tem que checar se não está re-enviando os stops para os lugares de Preços Inválidos...

;)

 
Flavio Jarabeck:

Poste o código inteiro... ninguém consegue adivinhar o começo de tudo, inclusive do problema...

Lembre-se sempre que em mercados de alta volatilidade você tem que checar se não está re-enviando os stops para os lugares de Preços Inválidos...

;)

Caro Flavio, muito obrigado pela atenção!

Segue o código completo:

//---bibliotecas e classes
#include <Trade\Trade.mqh>
CTrade trade;
//---
input int vol=2;//Qtd. de contratos
input ulong _deviation=3.00;//slippage
//---Magic Number
//ulong magicNum = 123456;
//---handles
int h_maM15;
int h_atr;
//---buffers
double maM15[];
double upAtr[];
double downAtr[];
//---structs:
MqlRates ratesM15[];
MqlTick negocio;
//---
double STL;
double PRC;
//---
bool ordPend;//para verificação de ordens pendentes
//---
int OnInit()
  {
//---média móvel em 15'
   h_maM15=iMA(_Symbol,PERIOD_M15,21,0,MODE_EMA,PRICE_CLOSE);
   if(h_maM15==INVALID_HANDLE)
     {
      Print("Erro ao criar a MA no PERIOD_M15. Código = ",GetLastError());
      return(INIT_FAILED);
     }
//---atr
   h_atr=iCustom(_Symbol,PERIOD_M15,"Mod_ATR_Trailing_Stop",14,2);
   if(h_atr==INVALID_HANDLE)
     {
      Print("Erro ao criar o indicador ATR. Código do Terminal nº ",GetLastError());
      return(INIT_FAILED);
     }
//---
   ArraySetAsSeries(maM15,true);
   ArraySetAsSeries(ratesM15,true);
   ArraySetAsSeries(upAtr,true);
   ArraySetAsSeries(downAtr,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---média móvel em 15'
   if(CopyBuffer(h_maM15,0,0,4,maM15)<0)
     {
      Alert("Erro ao copiar os dados da MA_M15 - Erro = ",GetLastError());
      return;
     }
//---vela de 15'
   if(CopyRates(_Symbol,PERIOD_M15,0,4,ratesM15)<0)
     {
      Alert("Erro ao copiar as informações da vela de 15 minutos - Erro = ",GetLastError());
      return;
     }
//---upAtr
   if(CopyBuffer(h_atr,0,0,4,upAtr)<0)
     {
      Alert("Erro ao copiar dados para o indicador ATR - Erro = ",GetLastError());
      return;
     }
//---downAtr
   if(CopyBuffer(h_atr,1,0,4,downAtr)<0)
     {
      Alert("Erro ao copiar dados para o indicador ATR - Erro = ",GetLastError());
      return;
     }
//---preço
   if(!SymbolInfoTick(_Symbol,negocio))
     {
      Alert("Erro ao copiar dados de preços. Erro nº ",GetLastError());
      return;
     }
//---verificação de ordens pendentes:
   ordPend=false;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      ulong _ticket = OrderGetTicket(i);
      string _symbol = OrderGetString(ORDER_SYMBOL);
      //ulong _magic = OrderGetInteger(ORDER_MAGIC);
      if(_symbol==_Symbol/*&&_magic==magicNum*/)
        {
         ordPend=true;
         break;
         Print("Já existe ordem pendente!");
        }
     }
//---estratégia de compra (exemplo)
   if(!PositionSelect(_Symbol) && !ordPend)
     {
      if(ratesM15[1].close>maM15[1]          &&
         downAtr[1]!=EMPTY_VALUE             &&
         ratesM15[0].open>maM15[0]           &&
         ratesM15[1].close>ratesM15[2].close &&
         ratesM15[2].close>ratesM15[3].close)
        {
         LOen();
        }
     }
//---estratégia de venda (exemplo)
   if(!PositionSelect(_Symbol) && !ordPend)
     {

      if(ratesM15[1].close<maM15[1]          &&
         upAtr[1]!=EMPTY_VALUE               &&
         ratesM15[0].open<maM15[0]           &&
         ratesM15[1].close<ratesM15[2].close &&
         ratesM15[2].close<ratesM15[3].close)
        {
         SHen();
        }
     }
//---Venda à mercado para encerrar operação de compra mais trailing-stop
   if(PositionSelect(_Symbol))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         trailingStopDown();
        }
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && downAtr[1]==EMPTY_VALUE)
        {
         Exit();
        }
     }
//---Compra à mercado para encerrar operação de venda mais trailing-stop
   if(PositionSelect(_Symbol))
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         trailingStopUp();
        }
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && upAtr[1]==EMPTY_VALUE)
        {
         Exit();
        }
     }
  }
//---Abertura de posição com compra à mercado
void LOen()
  {
   PRC=NormalizeDouble(negocio.ask,_Digits);
   if(trade.Buy(2,_Symbol,PRC,STL,0,"LOen"))
     {
      Print("Compra realizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Falha na compra. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
     }
  }
//---Abertura de posição com venda à mercado
void SHen()
  {
   PRC=NormalizeDouble(negocio.bid,_Digits);
   if(trade.Sell(2,_Symbol,PRC,STL,0,"SHen"))
     {
      Print("Venda realizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
     }
   else
     {
      Print("Falha na venda. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
     }
  }
//---Fechamento de posição à mercado
void Exit()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string _symbol = PositionGetSymbol(i);
      ulong _ticket = PositionGetInteger(POSITION_TICKET);
      if(_symbol==_Symbol)
        {
         if(trade.PositionClose(_ticket,_deviation))
           {
            Print("Operação finalizada com sucesso. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
           }
         else
           {
            Print("Falha no encerramento de posição. Cód. do Servidor nº ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
           }
        }
     }
  }
//---Trailing-stop em posição comprada
void trailingStopDown()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string _symbol = PositionGetSymbol(i);
      //ulong _magic = PositionGetInteger(POSITION_MAGIC);
      if(_symbol==_Symbol/*&&_magic==magicNum*/)
        {
         double priceOpen=PositionGetDouble(POSITION_PRICE_OPEN);
         ulong _ticket=PositionGetInteger(POSITION_TICKET);//ok
         double _stlAtual=PositionGetDouble(POSITION_SL);//ok
         if(downAtr[1]!=EMPTY_VALUE && downAtr[1]>_stlAtual+10)
           {
            double newSTL=NormalizeDouble(downAtr[1],_Digits)-MathMod(NormalizeDouble(downAtr[1],_Digits),0.5)-10;
            if(trade.PositionModify(_ticket,newSTL,0))
              {
               Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
               Comment("Dif Stop-Atr = ",MathAbs(newSTL-downAtr[1])-MathMod(MathAbs(newSTL-downAtr[1]),0.5));
              }
            else
              {
               Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
              }
           }
        }
     }
  }
//---Trailing-stop em posição vendida
void trailingStopUp()
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      string _symbol = PositionGetSymbol(i);
      //ulong _magic = PositionGetInteger(POSITION_MAGIC);
      if(_symbol==_Symbol/*&&_magic==magicNum*/)
        {
         double priceOpen=PositionGetDouble(POSITION_PRICE_OPEN);
         ulong _ticket=PositionGetInteger(POSITION_TICKET);//ok
         double _stlAtual=PositionGetDouble(POSITION_SL);//ok
         if(upAtr[1]!=EMPTY_VALUE)
           {
            double newSTL=NormalizeDouble(upAtr[1],_Digits)-MathMod(NormalizeDouble(upAtr[1],_Digits),0.5)+10;
            if(trade.PositionModify(_ticket,newSTL,0))
              {
               Print("Trailing-Stop funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
               Comment("Dif Stop-Atr = ",MathAbs(newSTL-upAtr[1])-MathMod(MathAbs(newSTL-upAtr[1]),0.5));
              }
            else
              {
               Print("Trailing-Stop NÃO está funcionando corretamente. Cód. Servidor = ",trade.ResultRetcode(),"\nDescrição: ",trade.ResultRetcodeDescription());
              }
           }
        }
     }
  }
//---End
 

Problema solucionado! Tanto pela função 'bool isNewBar()' quanto, com algumas modificações, pela biblioteca Lib CisNewBar.mqh. Só ainda não verifiquei qual das duas formas vai deixar o EA mais rápido, nem seus prós e contras.


Obrigado.

 
Daniel D. #:

Problema solucionado! Tanto pela função 'bool isNewBar()' quanto, com algumas modificações, pela biblioteca Lib CisNewBar.mqh. Só ainda não verifiquei qual das duas formas vai deixar o EA mais rápido, nem seus prós e contras.


Obrigado.

poderia me explicar como fez a correção? desde ja agradeço