Ordem com alteração no takeproit e stoploss

 

Após testes no em conta demo, executei hoje meu EA (MQL5) em conta real. Ele é de alvo curto, takeproit 25pts e stoploss 50pts.

Ocorre que o takeproit e stoploss entrava com pontuação diferente, dando resultado diferente.

Veja um exemplo do relatório:

 
relatório...

386948435 WINJ24 sell in 1 128 345 3286481281 0,00 0,00 0,00 0,00
386948490 WINJ24 buy out 1 128 335 3286481844 0,00 0,00 0,00  2,00
386948501 WINJ24 sell in 1 128 335 3286481868 0,00 0,00 0,00 0,00
386948555 WINJ24 buy out 1 128 320 3286482948 0,00 0,00 0,00  3,00
386948563 WINJ24 sell in 1 128 320 3286482976 0,00 0,00 0,00 0,00
386948565 WINJ24 buy out 1 128 320 3286482981 0,00 0,00 0,00 0,00
386948566 WINJ24 sell in 1 128 310 3286482996 0,00 0,00 0,00 0,00
386948569 WINJ24 buy out 1 128 310 3286483004 0,00 0,00 0,00 0,00
386948571 WINJ24 sell in 1 128 305 3286483018 0,00 0,00 0,00 0,00
386948595 WINJ24 buy out 1 128 290 3286483122 0,00 0,00 0,00  3,00
386948597 WINJ24 sell in 1 128 280 3286483136 0,00 0,00 0,00 0,00
386948633 WINJ24 buy out 1 128 280 3286483581 0,00 0,00 0,00 0,00
386948635 WINJ24 sell in 1 128 265 3286483592 0,00 0,00 0,00 0,00
386948638 WINJ24 buy out 1 128 285 3286483601 0,00 0,00 0,00 - 4,00








































































































































































 

Abaixo é parte do código. Esta bagunçado, rsss... Depois que ficar pronto prometo que arrumo rsss


input double lote = 1.0; //lote
input double stoploss = 50; // stoploss
input double takeProfit = 25; // takeProfit



input doublinput ulong magicNum = 123456;
input ulong desvPts = 50; //Desvio em Pontos
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN; 


bool posAberta;
bool ordPendente;



void OnTick()
{


 posAberta = false;  
   for(int i=PositionsTotal()-1; i>=0; i--)
   {
   string symbol = PositionGetSymbol(i);
   ulong magic = PositionGetInteger(POSITION_MAGIC);
   if( (symbol==_Symbol) && (magic==magicNum) )
      {
      posAberta = true; 
      break;
      }
   }
   
   ordPendente = 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) )
         {
      ordPendente = true;
      break;
      }
      }

  if( (LogicaCompra1() || LogicaCompra2()) && !posAberta && !ordPendente)   
    
      
{
double ask, bid, last;
      
      
      ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); 
      bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); 
      last = SymbolInfoDouble(_Symbol, SYMBOL_LAST);
      
   
    
            Comment("Compra");
            trade.Buy(lote, _Symbol, ask, ask-stoploss, ask+takeProfit, "COMPRA REALIZADA"); 

}  
      
   else if( (LogicaVenda1() || LogicaVenda2()) && !posAberta && !ordPendente )   
  
{
          double ask, bid, last;
      
      
      ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); 
      last = SymbolInfoDouble(_Symbol, SYMBOL_LAST);  
            
            Comment("Venda");
            trade.Sell(lote, _Symbol, bid, bid+stoploss, bid-takeProfit, "VENDA REALIZADA"); 
}

}




 

Em determinado momento, parou de abrir ordens.

No Diário observei a mensagem: "...56995914': failed exchange buy 1 WINJ24 at market sl: 128995 tp: 129070 [Invalid stops]"

A dúvida é, se o problema está no preço de entrada (pulando) ou se por alguma motivo o valor do takeprofit e stoploss está mudando.

Desde já agradeço a dica! Bons negócios a todos!
 
fabriciopduarte #:

Em determinado momento, parou de abrir ordens.

No Diário observei a mensagem: "...56995914': failed exchange buy 1 WINJ24 at market sl: 128995 tp: 129070 [Invalid stops]"

A dúvida é, se o problema está no preço de entrada (pulando) ou se por alguma motivo o valor do takeprofit e stoploss está mudando.

Desde já agradeço a dica! Bons negócios a todos!
Basicamente faltaria arredondar os valores de preço que voce informa da maneira a estarem alinhados corretamente, como voce usa normalizeDouble da impressão que esta. Mas na verdade tem algo errado e eh por isso esse erro. Pode estudar CSymbol::NormalizePrice para ver como normaliza certinho o preço ou até passar a chamar ela se achar mais interessante.
Documentation on MQL5: Standard Library / Trade Classes / CSymbolInfo / NormalizePrice
Documentation on MQL5: Standard Library / Trade Classes / CSymbolInfo / NormalizePrice
  • www.mql5.com
NormalizePrice(double) - CSymbolInfo - Trade Classes - Standard Library - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Ricardo Rodrigues Lucca #:
Basicamente faltaria arredondar os valores de preço que voce informa da maneira a estarem alinhados corretamente, como voce usa normalizeDouble da impressão que esta. Mas na verdade tem algo errado e eh por isso esse erro. Pode estudar CSymbol::NormalizePrice para ver como normaliza certinho o preço ou até passar a chamar ela se achar mais interessante.

Bom dia!

Fiz a alteração no código usando o NormalizePrice. No entanto o problema continuou.

Verifiquei o "Diário" e vi a seguinte mensagen: "Notifications    allowed 30 messages per minute".

Vou enviar o código e o relatório:

 
{
double ask, bid, last;
      
    
      ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); 
      last = SymbolInfoDouble(_Symbol, SYMBOL_LAST); 
      double Normalizedask = SymbolInfo.NormalizePrice(ask); 
      double Normalizedbid = SymbolInfo.NormalizePrice(bid); 
      double Normalizedlast = SymbolInfo.NormalizePrice(last); 
            Comment("Compra");
            trade.Buy(lote, _Symbol, Normalizedask, Normalizedask-stoploss, Normalizedask+takeProfit, "COMPRA REALIZADA"); 

}  
   else if( LogicaVenda() && !posAberta && !ordPendente )   
     

{
          double ask, bid, last;
      
      
      ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits); 
      bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
      last = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_LAST), _Digits); 
      double Normalizedask = SymbolInfo.NormalizePrice(ask); 
      double Normalizedbid = SymbolInfo.NormalizePrice(bid); 
      double Normalizedlast = SymbolInfo.NormalizePrice(last);       
            Comment("Venda");
            trade.Sell(lote, _Symbol, Normalizedbid, Normalizedbid+stoploss, Normalizedbid-takeProfit, "VENDA REALIZADA"); 
}
 

Segue o relatório abaixo. O retorno deveria ser 5,00 ou 10,00 (takeproit 25pts e stoploss 50pts ).

  0,00 0,00 0,00 - 22,00
3291184730 0,00 0,00 0,00 0,00
3291184784 0,00 0,00 0,00 0,00
3291184813 0,00 0,00 0,00 0,00
3291201764 0,00 0,00 0,00 - 14,00
3291248380 0,00 0,00 0,00 0,00
3291255790 0,00 0,00 0,00 - 9,00
3291290337 0,00 0,00 0,00 0,00
3291301447 0,00 0,00 0,00 - 13,00
3291310818 0,00 0,00 0,00 0,00
3291316410 0,00 0,00 0,00 - 9,00
3291327475 0,00 0,00 0,00 0,00
3291328806 0,00 0,00 0,00  4,00
3291329159 0,00 0,00 0,00 0,00
3291329808 0,00 0,00 0,00  1,00
3291330088 0,00 0,00 0,00 0,00
3291330100 0,00 0,00 0,00 - 1,00
3291330170 0,00 0,00 0,00 0,00
3291330183 0,00 0,00 0,00 - 1,00
3291330234 0,00 0,00 0,00 0,00
3291330245 0,00 0,00 0,00 - 1,00
3291330425 0,00 0,00 0,00 0,00
3291330440 0,00 0,00 0,00 - 1,00
3291331067 0,00 0,00 0,00 0,00
3291331339 0,00 0,00 0,00 - 1,00
3291331651 0,00 0,00 0,00 0,00
3291332472 0,00 0,00 0,00  2,0
 

O retorno deveria ser 5,00 ou 10,00 (takeproit 25pts e stoploss 50pts ). Percebi que na conta Demo, ocorre com muito menos frequência (se for relevante).

 
fabriciopduarte #:

Bom dia!

Fiz a alteração no código usando o NormalizePrice. No entanto o problema continuou.

Verifiquei o "Diário" e vi a seguinte mensagen: "Notifications    allowed 30 messages per minute".

Vou enviar o código e o relatório:

Voce tem que alocar o objeto e chamar o metodo name() antes de chamar o normalizePrice(). Não sei se foi feito. Outro ponto pra chamar atenção, voce normaliza o SL/TP depois de realizar soma ou subtracao e não antes.

Mas assim, não vai bater valor exato por TP/SL é a mercado então o slippage vai ficar grande mesmo.

 
Ricardo Rodrigues Lucca #:

Voce tem que alocar o objeto e chamar o metodo name() antes de chamar o normalizePrice(). Não sei se foi feito. Outro ponto pra chamar atenção, voce normaliza o SL/TP depois de realizar soma ou subtracao e não antes.

Mas assim, não vai bater valor exato por TP/SL é a mercado então o slippage vai ficar grande mesmo.

Ricardo Rodrigues Lucca #:

Voce tem que alocar o objeto e chamar o metodo name() antes de chamar o normalizePrice(). Não sei se foi feito. Outro ponto pra chamar atenção, voce normaliza o SL/TP depois de realizar soma ou subtracao e não antes.

Mas assim, não vai bater valor exato por TP/SL é a mercado então o slippage vai ficar grande mesmo.

 if( LogicaCompra() && !posAberta && !ordPendente)  
 {
double ask, bid, last;
string symbol = _Symbol; 
SymbolSelect(symbol,true);     
string symbolName = SymbolInfo.Name();
    
      ask = SymbolInfoDouble(symbolName, SYMBOL_ASK); 
      bid = SymbolInfoDouble(symbolName, SYMBOL_BID); 
      last = SymbolInfoDouble(symbolName, SYMBOL_LAST); 
             Comment("Compra");
           if (SymbolInfo.NormalizePrice(trade.Buy(lote, symbolName, ask, ask-stoploss, ask+takeProfit, "COMPRA REALIZADA"))) 
 {
             Print ("Ordem de compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
             Print("Preço de abertura...: ", ask );
             Print("Preço do Stoploss...: ", ask-stoploss );
             Print("Preço do TakeProfit...: ", ask+takeProfit );
             }
            else
            {
         Print ("Ordem de compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
            } 
}  
   else if( LogicaVenda() && !posAberta && !ordPendente )   
     {
double ask, bid, last;
string symbol = _Symbol; 
SymbolSelect(symbol,true);     
string symbolName = SymbolInfo.Name();      
    
      ask = SymbolInfoDouble(symbolName, SYMBOL_ASK); 
      bid = SymbolInfoDouble(symbolName, SYMBOL_BID); 
      last = SymbolInfoDouble(symbolName, SYMBOL_LAST); 
       
            Comment("Venda");
           if( SymbolInfo.NormalizePrice(trade.Sell(lote, symbolName, bid, bid+stoploss, bid-takeProfit, "VENDA REALIZADA")))
            {
             Print ("Ordem de venda - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
             Print("Preço de abertura...: ", bid );
             Print("Preço do Stoploss...: ", bid-takeProfit );
             Print("Preço do TakeProfit...: ", bid+stoploss );
             }
            else
            {
            Print ("Ordem de venda - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
            } 
            
            
}