[RESOLVIDO] OrderSend no mini indice e mini dolar ?

 

Estou tentando automatizar uma estratégia que tenho para usar no mini indice e mini dolar. No forex funciona bem, mas no mini indice e mini dolar as ordens não são enviadas e retorna um erro que não estou encontrando uma solução para resolver.

Como resolver esse problema ?


OrderSend

void sendOrder(int mn,
               bool sinalCompra,
               bool sinalVenda,
               double ls,
               string comment,
               bool operarCompra,
               bool operarVenda,
               double takeProfit,
               double stopLoss
               ){
   
     
   //variaveis responsaveis pelo envio da ordem
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check_result;    
   
   //zera objetos da memoria
   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check_result);
   
   //prices
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
  
   if(OrdersTotal() == 0 && PositionsTotal() == 0){
      
      if(sinalCompra && !sinalVenda && OrdersTotal() == 0){
         request.action       = TRADE_ACTION_DEAL;
         request.magic        = mn;
         request.symbol       =_Symbol;
         request.volume       = ls;
         request.price        = Ask; 
         request.sl           =0;
         request.tp           =0;
         if(stopLoss > 0){
            request.sl           =Ask - stopLoss * _Point;
         }
         if(takeProfit > 0){
            request.tp           =Ask + takeProfit * _Point; 
         }
           
         request.type         =ORDER_TYPE_BUY;
         request.type_filling =ORDER_FILLING_FOK; 
         request.comment      = comment; 
      }
      
      if(sinalVenda && !sinalCompra && OrdersTotal() == 0){
         request.action       = TRADE_ACTION_DEAL;
         request.magic        = mn;
         request.symbol       =_Symbol;
         request.volume       = ls;
         request.price        = Bid;
         request.sl           = 0;
         request.tp           = 0;
         if(stopLoss > 0){
            request.sl           =Bid + stopLoss * _Point;
         }
         if(takeProfit > 0){
            request.tp           =Bid - takeProfit * _Point;  
         }
          
         request.type         =ORDER_TYPE_SELL;
         request.type_filling =ORDER_FILLING_FOK; 
         request.comment      = comment;    
      }
      
      ResetLastError();
      if(!OrderSend(request, result)){
         PrintFormat("Erro em OrderSend: %d", GetLastError());
         //PrintFormat("Código de Retorno: %d", result.retcode);
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         return;
      }
   
   }//orderstotal
   
   
               
}


Erro: 

failed prices for  0.00 [Invalid request]


[RESOLVIDO]

Fala galera, abaixo como fiz para resolver e esta funcionando muito bem. Abraço e obrigado a todos!


void sendOrder(ulong mn,
               bool sinalCompra,
               bool sinalVenda,
               double ls,
               string comment,
               bool operarCompra,
               bool operarVenda,
               double takeProfit,
               double stopLoss){
               
    CTrade _trade;
    CSymbolInfo _simbolo;
    _trade.SetExpertMagicNumber(mn);
    _trade.SetTypeFilling(ORDER_FILLING_RETURN);
    
    double _price = 0;
    double _stopLoss = 0;
    double _takeProfit = 0;
    
    if(!_simbolo.Name(_Symbol)){
      PrintFormat("Erro tentando carregar ativo");
      return;
    }
    
    if(!_simbolo.RefreshRates()){
      PrintFormat("Erro tentando executar RefreshRates");
      return;
    }
    
    if(sinalCompra && operarCompra && PositionsTotal() == 0){
         _price = _simbolo.Ask();
         _stopLoss = _simbolo.NormalizePrice(_price - stopLoss * _Point);
         if(takeProfit > 0){
            _takeProfit = _simbolo.NormalizePrice(_price + takeProfit * _Point);
         } 
         if(!_trade.Buy(ls, _Symbol, _price, _stopLoss, _takeProfit, comment)){
            PrintFormat("Erro envio ordem compra: %d", GetLastError());
            PrintFormat("Retorno do erro: %s", _trade.CheckResultRetcodeDescription());
         }    
    }
    
    
    if(sinalVenda && operarVenda && PositionsTotal() == 0){
         _price = _simbolo.Bid();
         _stopLoss = _simbolo.NormalizePrice(_price + stopLoss * _Point);
         if(takeProfit > 0){
            _takeProfit = _simbolo.NormalizePrice(_price - takeProfit * _Point);
         }         
         if(!_trade.Sell(ls, _Symbol, _price, _stopLoss, _takeProfit, comment)){
            PrintFormat("Erro envio ordem venda: %d", GetLastError());
            PrintFormat("Retorno do erro: %s", _trade.CheckResultRetcodeDescription());
            
         }    
    
    }
               
               
               
}
 
Fernando Paiva:


Olá Fernando,

1) Ordem a mercado não precisa especificar o preço, mas se for informado deve estar normalizado para o TICK SIZE do instrumento.

2) O SL/TP  também devem estar normalizados para o TICK SIZE do instrumento,

Utilize a função  NormalizePrice() que está em /MQL5/include/trade/Symbol,mqh.  para normalizar o preço para o TICKSIZE do instrumento.

3) OrdersTotal() e PositionsTotal() conta TODAS  as ordens pendentes e TODAS posições  abertas no MT5.

 
Rogerio Giannetti Torres:

Olá Fernando,

1) Ordem a mercado não precisa especificar o preço, mas se for informado deve estar normalizado para o TICK SIZE do instrumento.

2) O SL/TP  também devem estar normalizados para o TICK SIZE do instrumento,

Utilize a função  NormalizePrice() que está em /MQL5/include/trade/Symbol,mqh.  para normalizar o preço para o TICKSIZE do instrumento.

3) OrdersTotal() e PositionsTotal() conta TODAS  as ordens pendentes e TODAS posições  abertas no MT5.

Fiz as mudanças mas ainda continua retornando o msm erro. 

OrderSend

void sendOrder(int mn,
               bool sinalCompra,
               bool sinalVenda,
               double ls,
               string comment,
               bool operarCompra,
               bool operarVenda,
               double takeProfit,
               double stopLoss
               ){
   
   CSymbolInfo simbolo;
   simbolo.Name(_Symbol);
     
   //variaveis responsaveis pelo envio da ordem
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check_result;    
   
   //zera objetos da memoria
   ZeroMemory(request);
   ZeroMemory(result);
   ZeroMemory(check_result);
   
   //prices
   //double Ask = simbolo.NormalizePrice(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   //double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
  
   if(OrdersTotal() == 0 && PositionsTotal() == 0){
      
      if(sinalCompra && !sinalVenda && OrdersTotal() == 0){
         request.action       = TRADE_ACTION_DEAL;
         request.magic        = mn;
         request.symbol       =_Symbol;
         request.volume       = ls;
         //request.price      = simbolo.Ask(); 
         request.sl           =0;
         request.tp           =0;
         if(stopLoss > 0){
            request.sl           = simbolo.NormalizePrice(simbolo.Ask() - stopLoss);
         }
         if(takeProfit > 0){
            request.tp           = simbolo.NormalizePrice(simbolo.Ask() + takeProfit); 
         }
           
         request.type         =ORDER_TYPE_BUY;
         request.type_filling =ORDER_FILLING_FOK; 
         request.comment      = comment; 
      }
      
      if(sinalVenda && !sinalCompra && OrdersTotal() == 0){
         request.action       = TRADE_ACTION_DEAL;
         request.magic        = mn;
         request.symbol       =_Symbol;
         request.volume       = ls;
         //request.price        = simbolo.Bid();
         request.sl           = 0;
         request.tp           = 0;
         if(stopLoss > 0){
            request.sl           = simbolo.NormalizePrice(simbolo.Bid() + stopLoss);
         }
         if(takeProfit > 0){
            request.tp           = simbolo.NormalizePrice(simbolo.Bid() - takeProfit);  
         }
          
         request.type         =ORDER_TYPE_SELL;
         request.type_filling =ORDER_FILLING_FOK; 
         request.comment      = comment;    
      }
      
      ResetLastError();
      if(!OrderSend(request, result)){
         PrintFormat("Erro em OrderSend: %d", GetLastError());
         //PrintFormat("Código de Retorno: %d", result.retcode);
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
         return;
      }
   
   }//orderstotal
   
   
               
}
 
Fernando Paiva:

Estou tentando automatizar uma estratégia que tenho para usar no mini indice e mini dolar. No forex funciona bem, mas no mini indice e mini dolar as ordens não são enviadas e retorna um erro que não estou encontrando uma solução para resolver.

Como resolver esse problema ?


OrderSend


Erro: 


Por que você não usa a biblioteca Trade? Todo esse código se transformaria em meia dúzia de linhas.

 
Fernando Paiva:

Fiz as mudanças mas ainda continua retornando o msm erro. 

OrderSend


1) O _Point ainda é necessário:  simbolo.NormalizePrice(simbolo.Ask() - stopLoss*_Point);

2) Printa os campos do request antes de dar o Send e assim vai enxergar o que está errado.

 

Fernado Paiva,

A maioria das corretoras brasileiras (senão todas) não aceitam preenchimento de ordem "fill or kill".

Experimente usar ORDER_FILLING_RETURN em vez de ORDER_FILLING_FOK no campo type_filling, que deve funcionar.

 
Alguém por favor pode me dizer como faço pra obter o tipo de ordem que está aberta? ja procurei mas nao encontrei um codigo de exemplo.
Razão: