Error na Ordem Conta Real

 

Olá eu sou novo na área tanto de programação mais principalmente de mercado criei um robô porém ele funciona normalmente na conta Demo mais na conta real ele da um erro ao enviar a Ordem,

Um erro chama invalid Prince  eu estou usando o BuyStop e SellStop alguém poderia me dar alguma dica obrigado.

 
envie seu codigo
 
#property copyright "Douglas Felipe"
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade/SymbolInfo.mqh>
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
#resource "\\Indicators\\Sup_Res.ex5" //CAMINHO DOS INDICADORES


//-----------Variavies Globais-------------//
input ENUM_TIMEFRAMES      TimeFrame      = PERIOD_M1; // TimeFrame
input double               Volume         = 1;         // Quantidade Inicial de Contratos
input string               HoraInicial    = "13:30";   // Horário de Início para novas operações
input string               HoraFinal      = "15:30";   // Horário de Término para novas operações
input string               HoraFechamento = "15:45";   // Horário de Fechamento para posições abertas
input double               Inp_Take_Profit = 0;       // Take Profit
input double               Inp_Stop_loss =  0;        //Stop Loss
input double               LimiteGain     = 0;        // Limite de Gain diário financeiro
input double               LimiteLoss     = 0;        // Limite de Loss diário financeiro
input ulong                desvPts        = 0;        //Desvio em Pontos
// Identificador do EA
int magic_number = 2122; 

//Obtem informações do ativo
CSymbolInfo simbolo; 
CTrade Trade;

//Classes para roteamento de ordens
MqlTick  tickes;
MqlRates rate[];
// Classes para controle de tempo
MqlDateTime hora_inicial, hora_final, hora_fechamento;

// Contagem para verificação de novo candle
static int bars;
//Estrutura para representar um sinal de compra ou venda
enum ENUM_SINAL {COMPRA = 1, VENDA  = -1, NULO   = 0};
//-----------Variavies Globais Intermediarias-------------//
int Indic; //Handle
double Resistencia[], Suporte[]; //Buffers
double stop_loss,take_profit;
double vol;



int OnInit()
  {
   
   stop_loss = Inp_Stop_loss;
   take_profit = Inp_Take_Profit;
   vol = Volume;
   
   if(!simbolo.Name(_Symbol))
   {
      Print("Erro ao carregar o ativo.");
      return INIT_FAILED;
   }
   // Verificando os Inputs //
   if (LimiteGain < 0 || LimiteLoss < 0 || Inp_Stop_loss < 0 || Inp_Take_Profit < 0)
   {
      Print("Parâmetros inválidos.");
      return INIT_FAILED;
   }
   // ----------------Chamando o Indicador--------------//
    Indic =iCustom(Symbol(),PERIOD_CURRENT,"::Indicators\\Sup_Res.ex5");    //Passe os parâmetros de cada indicador no final
    // Inicialização das variáveis de tempo
    TimeToStruct(StringToTime(HoraInicial), hora_inicial);
    TimeToStruct(StringToTime(HoraFinal), hora_final);
    TimeToStruct(StringToTime(HoraFechamento), hora_fechamento);
    // Verificação de inconsistências nos parâmetros de entrada
    if( (hora_inicial.hour > hora_final.hour || (hora_inicial.hour == hora_final.hour && hora_inicial.min > hora_final.min))
            || hora_final.hour > hora_fechamento.hour || (hora_final.hour == hora_fechamento.hour && hora_final.min > hora_fechamento.min))
      {
         Print("Os horários fornecidos estão inválidos.");
         return INIT_FAILED;
      }
   
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
//Evento invocado ao reiniciar o EA
void OnDeinit(const int reason)
 {
   printf("Reiniciando EA: %d", reason);
 }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  //----------------------Verificando Tickes------------------// 
   if(!SymbolInfoTick(_Symbol,tickes)){
       Print("Erro ao recuperar o Tiker", GetLastError());
       ResetLastError();
       return;
   }
   //Atualiza os dados de cotação do ativo
   if(!simbolo.RefreshRates())
      return;
   
   //Verifica se há um novo candle fechado
   bool novo_candle = IsNovoCandle();
   
   if(novo_candle)
   {        
           CondEntrada();
           //Verifica se o limite de gain ou loss foi atingido e encerra o processamento
            if (CheckLimites()) 
               return;
            //+------------------------------------------------------------------+
            //| Recebendo o Sinal de Compra ou Venda                                 |
            //+------------------------------------------------------------------+
             ENUM_SINAL sinal = CheckSinal();
             //+------------------------------------------------------------------+
            //| Chequendo se é Possivel Fazer Nova Entrada                                 |
            //+------------------------------------------------------------------+ 
             CheckNovaEntrada(sinal);
             //+------------------------------------------------------------------+
            //| Verifica se o horário limite de operações foi alcançado                                 |
            //+------------------------------------------------------------------+ 
            CheckHorarioFechamento();
      
     }   
  }

//+------------------------------------------------------------------+
//| Verifica se o horário atual está dentro do intervalo de tempo permitido                                       |
//+------------------------------------------------------------------+
//Se o horário limite para operações abertas foi alcançado, todas as ordens e operações abertas são fechadas imediatamente
void CheckHorarioFechamento()
 {
   if(IsHorarioFechamento())
   {
      if(IsPosicionado() || !IsOrdemLancada()) {
         Comment("Horário limite atingido. Encerrando ordens e posições abertas");
         Fechar();
      }
   }
 }
bool IsHorarioPermitido()
 {
   MqlDateTime hora_atual;
   TimeToStruct(TimeCurrent(), hora_atual); 
      
   if (hora_atual.hour >= hora_inicial.hour && hora_atual.hour <= hora_final.hour)
   {
      if ((hora_inicial.hour == hora_final.hour) 
            && (hora_atual.min >= hora_inicial.min) && (hora_atual.min <= hora_final.min))
         return true;
   
      if (hora_atual.hour == hora_inicial.hour)
      {
         if (hora_atual.min >= hora_inicial.min)
            return true;
         else
            return false;
      }
      
      if (hora_atual.hour == hora_final.hour)
      {
         if (hora_atual.min <= hora_final.min)
            return true;
         else
            return false;
      }
      
      return true;
   }
   
   return false;
 }
//Verifica se o horário limite para operações foi alcançado
bool IsHorarioFechamento()
 {
   MqlDateTime hora_atual;
   TimeToStruct(TimeCurrent(), hora_atual); 
   
   if (hora_atual.hour > hora_fechamento.hour)
      return true;
   
   if ((hora_atual.hour == hora_fechamento.hour) && (hora_atual.min >= hora_fechamento.min))
      return true;

   return false;
 }
 
//Verifica se um novo dia de operações foi iniciado
bool IsNovoDia()
 {
   static datetime OldDay = 0;
   
   MqlRates mrate[];    
   ArraySetAsSeries(mrate,true);      
   CopyRates(_Symbol,TimeFrame,0,2,mrate);
   
   datetime lastbar_time = mrate[0].time;
   
   MqlDateTime time;
   TimeToStruct(lastbar_time, time);
   
   if(OldDay < time.day_of_year)
   { 
      OldDay = time.day_of_year;
      return true;
   }
   
   return false;
 }
 //+------------------------------------------------------------------+
//|                   Bloco do Tempo Finalizado
//|                   Iniciando Bloco de Ordens
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|  Faz as Analises Para Saber se é Compra ou Venda                                      |
//+------------------------------------------------------------------+
 ENUM_SINAL CheckSinal()
 {
   double Cond = CondEntrada();
   double Candle = AnaliseCandle();
   
   if (Cond == 1 && Candle == 1)
            return COMPRA;
   
   if ( Cond == 0 && Candle == 0)
           return VENDA;
   
   
 
   
   
   return NULO;
 }
 double AnaliseCandle(){
   double Tipo = TipoCandle();
   double martelo = Martelo(); 
   double marobuzo = Marobuzo();
   //---------------------------Compra--------------------------------//
   if(Tipo == 1)
     {
       if(marobuzo == 1 || martelo == 1)
          return 1;
     }
   //---------------------------Venda--------------------------------//
   if(Tipo == 0)
     { 
       if(marobuzo == 1 || martelo == 0)
          return 0;
     }
   return -1;
 }
 double CondEntrada(){
   int copie1 = CopyBuffer(Indic,1,0,1,Resistencia);
   int copie2 = CopyBuffer(Indic,0,0,1,Suporte);
   double C = InfoCandle("C",1);
   double O = InfoCandle("O",1);
   double H = InfoCandle("H",1);
   double L = InfoCandle("L",1);
   double compCandle = Resistencia[0]+15*_Point;
   double vendCandle = Suporte[0]-15*_Point;
   
   
   if(copie1 == 1 && copie2 == 1){

    //+------------------------------------------------------------------+
   //|         NO Rompimento
   //+------------------------------------------------------------------+
    if(O < Resistencia[0] && C > Resistencia[0] && C >= compCandle)
           {
            return 1;
           }

    if(O > Suporte[0] && C < Suporte[0] && C <= vendCandle)
            {
               return 0;
            }
   
       
   
   }
   
   return -1;
 }
//+------------------------------------------------------------------+
//|  Faz a Checagem de Compra ou Venda
//|  Verifica se existe alguma posição em aberto                                         |
//+------------------------------------------------------------------+
 void CheckNovaEntrada(ENUM_SINAL sinal){
      if (IsHorarioPermitido() && !IsPosicionado()){
         if (sinal == COMPRA) 
         {
            Compra();
            
         }
         else if (sinal == VENDA)
         {
              Venda();
         }
      
      }
 }
void Compra(){
      double Price  = InfoCandle("H",1);
      Price = NormalizeDouble(Price,_Digits); 
      double SL = Price - stop_loss;   
      SL =   NormalizeDouble(SL,_Digits);
      double TP = Price + take_profit;
      TP =   NormalizeDouble(TP,_Digits);
      
      datetime expiration= TimeTradeServer()+PeriodSeconds(PERIOD_M2);
      if(!Trade.BuyStop(vol,Price,_Symbol,SL,TP,ORDER_TIME_SPECIFIED,expiration,NULL)){
                            Print("Erro ao enviar a ordem! ", GetLastError());
                            ResetLastError();
                            return;
       }else{
             CheckRequizicao();
       }
 
 }
 void Venda(){
      double Price = InfoCandle("L",1);
      Price = NormalizeDouble(Price,_Digits); 
      double SL = Price + stop_loss;   
      SL =   NormalizeDouble(SL,_Digits);
      double TP = Price - take_profit;
      TP =   NormalizeDouble(TP,_Digits);
      datetime expiration= TimeTradeServer()+PeriodSeconds(PERIOD_M2);
      if(!Trade.SellStop(vol,Price,_Symbol,SL,TP,ORDER_TIME_SPECIFIED,expiration,NULL)){
                            Print("Erro ao enviar a ordem! ", GetLastError());
                            ResetLastError();
                            return;
       }else{
            CheckRequizicao();
       }
 
 }
 void CheckRequizicao(){
       if(Trade.ResultRetcode() == 10008 || Trade.ResultRetcode() == 10009){
                     Print("Ordem colocado com sucesso ",Trade.ResultRetcode());
             }else{
                    Print("Error ao Enviar ordem ",Trade.ResultRetcode());
              }
 
 }
 //+------------------------------------------------------------------+
//|                   Bloco de Ordens  Finalizado
//|                   Iniciando Bloco de Checagens
//+------------------------------------------------------------------+
 
//Verifica se há um novo candle fechado
bool IsNovoCandle()
 {
   if(bars != Bars(_Symbol, _Period))
    {
       bars = Bars(_Symbol, _Period);
       return true;
    }
    
   return false;
}
  //Verifica se há posição no ativo
bool IsPosicionado()
 {  
   return PositionSelect(_Symbol);
 }

//Verifica se há alguma ordem lançada no ativo
bool IsOrdemLancada()
 {  
   for(int i=OrdersTotal()-1; i>=0; i--)
   {
      OrderGetTicket(i);
      if(OrderGetString(ORDER_SYMBOL)==_Symbol)
         return true;
   }
   return false;
 }
 //Verifica se há ordens pendentes ou posições abertas e as fecha imediatamente
void Fechar()
{  
   FecharOrdens();
   
   FecharPosicao();
}

//Fecha ordens abertas
void FecharOrdens()
 {
   
   for(int i = OrdersTotal()-1; i>=0; i--)
         {
            string symbol = PositionGetSymbol(i);
            ulong magic = PositionGetInteger(POSITION_MAGIC);
            if(symbol == _Symbol && magic == magic_number)
               {
                  ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
                  if(Trade.OrderDelete(PositionTicket))
                     {
                        Print("Ordem Fechada - sem falha. ResultRetcode: ", Trade.ResultRetcode(), ", RetcodeDescription: ", Trade.ResultRetcodeDescription());
                        Comment("Ordem Fechada");
                     }
                  else
                     {
                        Print("Ordem Fechada - com falha. ResultRetcode: ", Trade.ResultRetcode(), ", RetcodeDescription: ", Trade.ResultRetcodeDescription());
                     }
               }
         }
 }
 
//+------------------------------------------------------------------+
//| Fechando Posições Abertas                                        |
//+------------------------------------------------------------------+
void FecharPosicao()
 {
   for(int i = PositionsTotal()-1; i>=0; i--)
         {
            string symbol = PositionGetSymbol(i);
            ulong magic = PositionGetInteger(POSITION_MAGIC);
            if(symbol == _Symbol && magic == magic_number)
               {
                  ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
                  if(Trade.PositionClose(PositionTicket, desvPts))
                     {
                        Print("Posição Fechada - sem falha. ResultRetcode: ", Trade.ResultRetcode(), ", RetcodeDescription: ", Trade.ResultRetcodeDescription());
                        Comment("Posição Fechada");
                     }
                  else
                     {
                        Print("Posição Fechada - com falha. ResultRetcode: ", Trade.ResultRetcode(), ", RetcodeDescription: ", Trade.ResultRetcodeDescription());
                     }
               }
         }
 }
 
 //+------------------------------------------------------------------+
//| Chequendo se pelo Saldo Financeiro pode fazer nova entrada                                        |
//+------------------------------------------------------------------+
 bool CheckLimites()
 {

       if (LimiteGain > 0 && GetSaldoFinanceiro() >= LimiteGain)
   {
      Fechar();
      Comment("Limite de Gain diário batido.");
      return true;
   }
   
   if (LimiteLoss > 0 && GetSaldoFinanceiro() <= (LimiteLoss*-1)) {
      Fechar();
      Comment("Limite de Loss diário batido.");
      return true;
   }
   
   return false;
  
 }
 //+---------------------------------    ---------------------------------+
//| Verifica o Saldo Financeiro                                    |
//+------------------------------------------------------------------+
 double GetSaldoFinanceiro()
 {

   datetime end = TimeCurrent();
   datetime start = end - (end % 86400); // Hora inicial do dia

   HistorySelect(start, end);
   int deals = HistoryDealsTotal();

   double deal_profit = 0;
   
   for(int i=0 ; i < deals; i++)
   {
      
      ulong deal_ticket = HistoryDealGetTicket(i);
      if(deal_ticket > 0) 
      {
         string deal_symbol = HistoryDealGetString(deal_ticket, DEAL_SYMBOL);
   
         if (deal_symbol == _Symbol) 
            deal_profit = deal_profit + HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
      }
   }
  
   return deal_profit;
 }
 //+---------------------------------    ---------------------------------+
//| Analisando Candles                                  |
//+------------------------------------------------------------------+
double InfoCandle(string Condicao,int candle){
   ArraySetAsSeries(rate, true);
   CopyRates(_Symbol,TimeFrame, 0, 3, rate);
   double valor = 0;
   
   if(StringCompare(Condicao,"C") == 0) 
       valor = rate[candle].close;
   if(StringCompare(Condicao,"O") == 0) 
       valor = rate[candle].open; 
   if(StringCompare(Condicao,"L") == 0)
       valor = rate[candle].low;
   if(StringCompare(Condicao,"H") == 0) 
       valor = rate[candle].high; 
        
   return valor;
}
double InfoCorpoCandle(string Condicao){
   
   double valor = 0;
   double amplitude=InfoCandle("H",1)-InfoCandle("L",1);
   // Qual é o tamanho relativo (em porcentagem) do corpo em relação ao tamanho da vela?
   double corpo=amplitude==0 ? 100 :(MathAbs(InfoCandle("C",1)-InfoCandle("O",1))/amplitude*100);
   // Qual é o tamanho relativo (em porcentagem) da sombra/pavio superior em relação ao tamanho da vela?
   double sombra_superior=amplitude==0 ? 0 :(MathAbs(InfoCandle("H",1)-MathMax(InfoCandle("O",1),InfoCandle("C",1)))/amplitude*100);
   // Qual é o tamanho relativo (em porcentagem) da sombra/pavio inferior em relação ao tamanho da vela?
   double sombra_inferior=amplitude==0 ? 0 :(MathAbs(MathMin(InfoCandle("O",1),InfoCandle("C",1)) -InfoCandle("L",1))/amplitude*100);
   
   if(StringCompare(Condicao,"C") == 0) 
       valor = corpo;
   if(StringCompare(Condicao,"S") == 0) 
       valor = sombra_superior; 
   if(StringCompare(Condicao,"I") == 0)
       valor = sombra_inferior;
   
        
   return valor;
}
double TipoCandle(){
   
  if(InfoCandle("C",1)> InfoCandle("O",1))
      return 1;
  if(InfoCandle("O",1) > InfoCandle("C",1))
      return 0;
  return -1;
}
double Marobuzo(){
      double CorpoMinimo=40; // Corpo mínimo (%)
      double CorpoMaximo=100; // Corpo máximo (%)
      double Sombra=30;      // Sombra menor que (%)
      if(InfoCorpoCandle("C")>=CorpoMinimo && InfoCorpoCandle("C")<=CorpoMaximo
         && InfoCorpoCandle("S") < Sombra && InfoCorpoCandle("I") < Sombra
      ){
           return 1; 
      }
      return -1;
}
double Martelo(){
      double CorpoMinimo=20; // Corpo mínimo (%)
      double CorpoMaximo=40; // Corpo máximo (%)
      double Sombra= 50;      // Sombra maior que (%)
      
      if(InfoCorpoCandle("C")>=CorpoMinimo && InfoCorpoCandle("C")<=CorpoMaximo)
        {
         if (InfoCorpoCandle("I") > Sombra)
                  return 1;
         if(InfoCorpoCandle("S") > Sombra)
                  return 0;
        }
        return -1;
}


Descubra novos recursos para o MetaTrader 5 com a comunidade e os serviços MQL5
Descubra novos recursos para o MetaTrader 5 com a comunidade e os serviços MQL5
  • 2021.04.22
  • www.mql5.com
MQL5: linguagem de estratégias de negociação inseridas no Terminal do Cliente MetaTrader 5. A linguagem permite escrever seus próprios sistemas automáticos de negócios, indicadores técnicos, scripts e bibliotecas de funções
 
Douglas Felipe:

Olá eu sou novo na área tanto de programação mais principalmente de mercado criei um robô porém ele funciona normalmente na conta Demo mais na conta real ele da um erro ao enviar a Ordem,

Um erro chama invalid Prince  eu estou usando o BuyStop e SellStop alguém poderia me dar alguma dica obrigado.

Olá Douglas!


Inclua essa função no seu código e, onde você calcula Price, SL e TP, substitua NormalizeDouble por NormalizePrice e teste novamente pra ver se muda alguma coisa:

//+--------------------------------------------------------------------------------------------------------------------+
//| This function normalizes and adjusts the price to the TICK SIZE                                                    |
//+--------------------------------------------------------------------------------------------------------------------+
double NormalizePrice(double Price)
  {
   //--- Get the minimal price change
   double TickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

   //--- Return the price normalized
   if(TickSize == 0.0) {return(NormalizeDouble(Price, _Digits));}

   //--- Return the price normalized and adjusted to the TICK SIZE
   return(NormalizeDouble(MathRound(Price / TickSize ) * TickSize, _Digits));
  }
 

@Vinicius de Oliveira

Muito Obrigado Amigo Funcionou muito bem só o tempo de expiração que não funcionou você tem alguma ideia porque?Funcionou normalmente na conta demo tambem o tempo de expiração da ordem que estranho

Vinicius de Oliveira
Vinicius de Oliveira
  • 2021.04.19
  • www.mql5.com
Perfil do Trader
 
Eu ia falar a mesma coisa que o Vinicius, outro ponto que vc tem que ajustar, é que o magic number não foi  setado no programa, sendo assim bem provavel que algumas funções não irão funcionar corretamente
 

boa tarde!

Estou sem conexão no MT4, não é problema com internet local. 

Alguém saberia me informar o problema e a solução?

 
Douglas Felipe:

@Vinicius de Oliveira

Muito Obrigado Amigo Funcionou muito bem só o tempo de expiração que não funcionou você tem alguma ideia porque?Funcionou normalmente na conta demo tambem o tempo de expiração da ordem que estranho

Boa tarde!

Que bom que deu certo! 🤝


Além da sugestão do Eduardo sobre o Magic Number, em relação à expiração da ordem você precisa ver nas especificações do ativo os modos de expiração de ordens permitidas. A função abaixo pode lhe ajudar com isso (talvez precise alguma implementação para usar no seu código):

//=== ADICIONA A FUNÇÃO ABAIXO:

//+--------------------------------------------------------------------------------------------------------------------+
//| Verifica se um modo de expiração especifico é permitido                                                            |
//+--------------------------------------------------------------------------------------------------------------------+
bool IsExpiratTypeAllowed(int exp_type)
  {
   //--- Obtém o valor da propriedade que descreve os modos de expiração permitidos
   int expiration = (int)SymbolInfoInteger(_Symbol, SYMBOL_EXPIRATION_MODE);
   //--- Retorna true, se o modo exp_type é permitido
   return((expiration&exp_type)==exp_type);
  }


//=== ADICIONA ESSA VARIÁVEL GLOBAL:

//--- Orders properties
ENUM_ORDER_TYPE_TIME OrderTypeTime;


//=== FAZ ESSA VERIFICAÇÃO EM OnInit():

//--- Checks allowed properties
if(IsExpiratTypeAllowed(SYMBOL_EXPIRATION_GTC)) {OrderTypeTime = ORDER_TIME_GTC;} else {OrderTypeTime = ORDER_TIME_DAY;}


//=== UTILIZA O VALOR DA VARIÁVEL OrderTypeTime PARA request.type_time.


Avise se der erro que a gente vai tentando fazer os ajustes necessários.

 
VctorPinho:

boa tarde!

Estou sem conexão no MT4, não é problema com internet local. 

Alguém saberia me informar o problema e a solução?

Boa tarde!


Inicie um novo tópico aqui relatando melhor o problema, descrevendo o que você já tentou e não deu certo e incluindo imagens da sua tela (lembre de ocultar nas imagens dados que considerar sigilosos / pessoais) ...


Talvez assim, alguém consiga lhe ajudar ... 👍

 

Obrigado pelas dicas eu vou testar elas só mais uma duvida para setar corretamente o magic number usa este código:

SetExpertMagicNumber(magic_number)  dentro do OnInit().

Esta Certo?

 

@Vinicius de Oliveira

Muito Obrigado pela ajuda mais eu estou com duvidas e medo rsrs testei na conta demo funciona normalmente na conta real esta dando erro de invalid prince já estou preocupado de rodar este robo em conta real gostaria de saber se além do magic number se existe mais alguma coisas que preciso corrigir para colocar em conta real . 

Vinicius de Oliveira
Vinicius de Oliveira
  • 2021.04.19
  • www.mql5.com
Perfil do Trader
Razão: