OrderSend error 10016 invalid stops

Para adicionar comentários, por favor Faça o login ou registrar
tito.vinicius
263
tito.vinicius  

Fala pessoal, bom dia.

Defini como trailing stop a média móvel. Logo, quando realizo o teste no Backtest o stop movimenta conforme a média definida.

Contudo, quando vou para a conta demo recebo a seguinte mensagem: "OrderSend error 10016 invalid stops". Já alterei período, o shift, o modelo da média e continua aconcendo este problema.

Olhei o stop mínimo permitido pela corretora e os valores adotados pela média estão conforme estipulado. Segue abaixo o código:

// Tralling Stop Moving Average
   if(UseTrailingStop==true && PositionTypeTito(_Symbol)!=-1 && Type=="moving")
   {if(PositionTypeTito() == POSITION_TYPE_BUY)
     {TrailingStopPrice(_Symbol,ma20[1],MinimumProfit);}
   if(PositionTypeTito() == POSITION_TYPE_SELL)
     {TrailingStopPrice(_Symbol,ma17[1],MinimumProfit);}  

 Segue a função TrailingStopPrice()

//+------------------------------------------------------------------+
//|Tralling Stop Price                                               |
//+------------------------------------------------------------------+
bool TrailingStopPrice(string pSymbol,double pTrailPrice,int pMinProfit=0)
  {
  if(PositionSelect(pSymbol) == true && pTrailPrice > 0)
        {
           MqlTradeRequest request;
      MqlTradeResult result;
      ZeroMemory(request);
                request.action = TRADE_ACTION_SLTP;
                request.symbol = pSymbol;
                
                long posType = PositionGetInteger(POSITION_TYPE);
                double currentStop = PositionGetDouble(POSITION_SL);
                double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                
                double point = SymbolInfoDouble(pSymbol,SYMBOL_POINT);
                int digits = (int)SymbolInfoInteger(pSymbol,SYMBOL_DIGITS);
                
        
                double minProfit = pMinProfit * point;
                                
                currentStop = NormalizeDouble(currentStop,digits);
                pTrailPrice = NormalizeDouble(pTrailPrice,digits);
                
                double currentProfit;
                btp=openPrice+TP*Point();
      btp=NormalizeDouble(btp,Digits());
      stp=openPrice-TP*Point();
      stp=NormalizeDouble(stp,Digits());
                
                int retryCount = 0;
                int checkRes = 0;
                
                double bid = 0, ask = 0;
                
                do 
                {
                        if(posType == POSITION_TYPE_BUY)
                        {
                                bid = SymbolInfoDouble(pSymbol,SYMBOL_BID);
                                currentProfit = bid - openPrice;
                                if(pTrailPrice > currentStop && currentProfit >= minProfit) 
                                {
                                        request.sl = pTrailPrice;
                                        request.tp = btp;
                                        bool sent = OrderSend(request,result);
                                }
                                else return(false);
                        }
                        else if(posType == POSITION_TYPE_SELL)
                        {
                                ask = SymbolInfoDouble(pSymbol,SYMBOL_ASK);
                                currentProfit = openPrice - ask;
                                if((pTrailPrice < currentStop  || currentStop == 0) && currentProfit >= minProfit)
                                {
                                        request.sl = pTrailPrice;
                                        request.tp = stp;
                                        bool sent = OrderSend(request,result);
                                }
                                else return(false);
                        }
                        
                        checkRes = CheckReturnCode(result.retcode);
                
                        if(checkRes == CHECK_RETCODE_OK) break;
                        else if(checkRes == CHECK_RETCODE_ERROR)
                        {
                                string errDesc = TradeServerReturnCodeDescription(result.retcode);
                                Alert("Trailing stop: Error ",result.retcode," - ",errDesc);
                                break;
                        }
                        else
                        {
                                Print("Server error detected, retrying...");
                                Sleep(RETRY_DELAY);
                                retryCount++;
                        }
                }
                while(retryCount < MAX_RETRIES);
        
                if(retryCount >= MAX_RETRIES)
                {
                        string errDesc = TradeServerReturnCodeDescription(result.retcode);
                        Alert("Max retries exceeded: Error ",result.retcode," - ",errDesc);
                }
                
                string errDesc = TradeServerReturnCodeDescription(result.retcode);
                Print("Trailing stop: ",result.retcode," - ",errDesc,", Old SL: ",currentStop,", New SL: ",request.sl,", Bid: ",bid,", Ask: ",ask,", Stop Level: ",SymbolInfoInteger(pSymbol,SYMBOL_TRADE_STOPS_LEVEL));
                
                if(checkRes == CHECK_RETCODE_OK) return(true);
                else return(false);
        }
        else return(false);
} 

Se alguém puder me ajudar, ficaria muito grato.

Rogerio Giannetti Torres
3155
Rogerio Giannetti Torres  
tito.vinicius:


Bom dia,

Vou dar uma sugestão. Para normalizar os preços de um ativo para tickSize correto faça como mostrado abaixo.

SymbolInfoInteger(_Symbol,SYMBOL_DIGITS,digits);
SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE,tickSize);

preco=NormalizeDouble(MathRound(preco/tickSize)*tickSize,digits);

tito.vinicius
263
tito.vinicius  
Rogerio Giannetti Torres:

Bom dia,

Vou dar uma sugestão. Para normalizar os preços de um ativo para tickSize correto faça como mostrado abaixo.

Obrigado pela ajuda Rogério. Funcionou perfeitamente.

Mais uma vez muito obrigado.

Nelson Silva
1889
Nelson Silva  
tito.vinicius:

Obrigado pela ajuda Rogério. Funcionou perfeitamente.

Mais uma vez muito obrigado.

   Oi, 


   Aproveitando o ensejo, o que seria esse tickSize eu não entendi? Por que tudo isso pra enviar o preço?

Rogerio Giannetti Torres
3155
Rogerio Giannetti Torres  
Nelson Silva:

   Oi, 


   Aproveitando o ensejo, o que seria esse tickSize eu não entendi? Por que tudo isso pra enviar o preço?

Bom dia Nelson

o tamanho do tick, tradução literal para tick size, define como o preço de um instrumento se movimenta. Exemplos:

Cotação de ações o tick size é 0,01 então os preços para ações se movimentam de 0,01 em 0,01 centavos:  12,21 -> 12,22 - 12,23

Cotação do DOL/BRL na B3 o tick size é 0,50 então os preços se movimentam de 0,50 em 0,50 centavos: 4 090,00 --> 4090,50 --> 4091,00

Cotação do contrato de futuros INDICE o tick size é de 5 pontos então os preços se movem de 5 em 5 pontos  103100 --> 103105 --> 103010.

Cotação do MINI S&P 500 o tick size é de 0,25 então os preços se movem de 0,25 de 0,25 centavos: 2992,00 --> 2992,25 --> 2992,50.

Só podemos emitir ordens com os valores de preço com tick size correto , isso vale para preço da ordem, preço do stop loss e preço do take profit.

At.te

Rogério.

Nelson Silva
1889
Nelson Silva  
Rogerio Giannetti Torres:

Bom dia Nelson

o tamanho do tick, tradução literal para tick size, define como o preço de um instrumento se movimenta. Exemplos:

Cotação de ações o tick size é 0,01 então os preços para ações se movimentam de 0,01 em 0,01 centavos:  12,21 -> 12,22 - 12,23

Cotação do DOL/BRL na B3 o tick size é 0,50 então os preços se movimentam de 0,50 em 0,50 centavos: 4 090,00 --> 4090,50 --> 4091,00

Cotação do contrato de futuros INDICE o tick size é de 5 pontos então os preços se movem de 5 em 5 pontos  103100 --> 103105 --> 103010.

Cotação do MINI S&P 500 o tick size é de 0,25 então os preços se movem de 0,25 de 0,25 centavos: 2992,00 --> 2992,25 --> 2992,50.

Só podemos emitir ordens com os valores de preço com tick size correto , isso vale para preço da ordem, preço do stop loss e preço do take profit.

At.te

Rogério.

   Vlw, Rogério!

   Ainda não precisei usar essa opção nos Eas que desenvolvi, maioria no índice.

   Vou verificar isso aí pra questões de compatibilidade futuras.

tito.vinicius
263
tito.vinicius  
Nelson Silva:

   Vlw, Rogério!

   Ainda não precisei usar essa opção nos Eas que desenvolvi, maioria no índice.

   Vou verificar isso aí pra questões de compatibilidade futuras.

Fala Nelson, blz?


E depois da dica do Rogério, daí me dei conta como faz sentido a lógica explicada por ele. Como o gatilho de compra e venda do meu EA era média móveis, os valores resultantes das médias não eram redondos conforme o Tick Size do DOL/BRL ( Cotação do DOL/BRL na B3 o tick size é 0,50 então os preços se movimentam de 0,50 em 0,50 centavos: 4 090,00 --> 4090,50 --> 4091,00). Logo, o preço do meu trailing stop não condizia com tick size do ativo. DAndo o erro 10016. Talvez ainda não aconteceu contigo pq o vc deve estar usando o preço como gatilho de compra e venda.

Nelson Silva
1889
Nelson Silva  
tito.vinicius:

Fala Nelson, blz?


E depois da dica do Rogério, daí me dei conta como faz sentido a lógica explicada por ele. Como o gatilho de compra e venda do meu EA era média móveis, os valores resultantes das médias não eram redondos conforme o Tick Size do DOL/BRL ( Cotação do DOL/BRL na B3 o tick size é 0,50 então os preços se movimentam de 0,50 em 0,50 centavos: 4 090,00 --> 4090,50 --> 4091,00). Logo, o preço do meu trailing stop não condizia com tick size do ativo. DAndo o erro 10016. Talvez ainda não aconteceu contigo pq o vc deve estar usando o preço como gatilho de compra e venda.

     Realmente,

    

     Eu vou construir um trailiing pela MédiaMóvel e simular essa situação, interessante, o trailing que eu to usando nos Eas é somente com passo.

Para adicionar comentários, por favor Faça o login ou registrar