Meu 1º EA, problemas horário, estratégia

 
Olá amigos, estou com dificuldades no meu 1º EA, com a estratégia que compra a mercado quando a mínima anterior cruzou a bollinger inferior tendo tbm adx, di+,di- e a distancia das bandas como filtros, e na venda inverte. Ele não esta seguindo a estratégia, e tbm não estou conseguindo colocar um horário limite para ele abrir as posições.

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.20
  • 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
Arquivos anexados:
beta.mq5  28 kb
DUVIDA.PNG  44 kb
 
Romeu Masselai:
Olá amigos, estou com dificuldades no meu 1º EA, com a estratégia que compra a mercado quando a mínima anterior cruzou a bollinger inferior tendo tbm adx, di+,di- e a distancia das bandas como filtros, e na venda inverte. Ele não esta seguindo a estratégia, e tbm não estou conseguindo colocar um horário limite para ele abrir as posições.

Boa noite!


Eu corrigi os alertas ao compilar. Teste aí se mudou alguma coisa:


//+------------------------------------------------------------------+
//|                                                  my_first_ea.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- PARÂMETROS DE ENTRADA

input int      Stop_Loss=30;                     // STOP LOSS
input int      Stop_Gain=10;                     // STOP GAIN
input int      EA_Magic_Number=12345;            // MAGIC NUMBER
input double   Lote=1.0;                         // TAMANHO DO LOTE

input int      Periodo_ADX=9;                    // PERIODO ADX
input int      adx_atr=1;                        // ATRASO ADX
input int      adx_max=26;                       // FILTRO ADX MAXIMO
input int      Periodo_Bollinger=20;             // PERIODO BOLLINGER
input double   Desvio_Bollinger=2.5;             // DESVIO BANDAS DE BOLLINGER
input double   Afastamento_Maximo_BB=200.0;      // AFASTAMENTO MAXIMO BANDAS DE BOLLINGER



//--- OUTROS PARÂMETROS

int     Manipulador_ADX;                         // HANDLE ADX
int     Manipulador_BB;                          // HANDLE BB
double  DI_Mais[];                               // ARRAY DE ARMAZENAMENTO DI MAIS
double  DI_menos[];                              // ARRAY DE ARMAZENAMENTO DI MENOS
double  Valor_ADX[];                             // ARRAY DE ARMAZENAMENTO ADX
double  BB_Sup[];                                // ARRAY DE ARMAZENAMENTO BB SUPERIOR
double  BB_Inf[];                                // ARRAY DE ARMAZENAMENTO INFERIOR
double  BB_Med[];                                // ARRAY DE ARMAZENAMENTO BB MEDIA
double  p_close;                                 // VARIAVEL PARA ARMAZENAR O VALOR DO FECHAMENTO
double  p_open;                                  // VARIAVEL PARA ARMAZENAR O VALOR DA ABERTURA
double  p_max;                                   // VARIAVEL PARA ARMAZENAR O VALOR DA MAXIMA
double  p_min;                                   // VARIAVEL PARA ARMAZENAR O VALOR DA MINIMA
int     STL;                                     // STOP LOSS
int     STG;                                     // STOP GAIN

//+------------------------------------------------------------------+
//| Função de inicialização do EA                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

  Manipulador_ADX = iADX(_Symbol,PERIOD_CURRENT,Periodo_ADX);
  Manipulador_BB  = iBands(_Symbol,PERIOD_CURRENT,Periodo_Bollinger,0,Desvio_Bollinger,PRICE_CLOSE);
  
  if (Manipulador_ADX < 0 || Manipulador_BB < 0)
   {
      Alert("Erro ao criar handles para indicadores - erro: ",GetLastError(),"!!");
      return(-1);
     }
     //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4
   STL = Stop_Loss;
   STG = Stop_Gain;
   if(_Digits==5 || _Digits==3)
     {
      STL = STL*10;
      STG = STG*10;
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Função de finalização do EA                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {  
   IndicatorRelease(Manipulador_ADX);             // FINALIZAR HANDLE ADX
   IndicatorRelease(Manipulador_BB);              // FINALIZAR HANDLE BB
  }
 
  
//+------------------------------------------------------------------+
//| Função tick EA                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Verificar se temos candles suficientes
   if(Bars(_Symbol,_Period)<60) // se o total de candles for inferior a 60
     {
      Alert("Temos menos de 60 barras!!");
      return;
     } 
   
   static datetime Old_Time;                                       // Usaremos a variável estática Old_Time para servir o horário do bar.
   datetime New_Time[1];                                           // A cada execução do OnTick verificaremos o tempo de compasso atual com o salvo. 
   bool IsNewBar=false;                                            // Se o tempo da barra não for igual ao tempo economizado, indica que temos um novo tique.
   
   
   int copied = CopyTime(_Symbol,PERIOD_CURRENT,0,1,New_Time);     // Copiando a última barra de tempo para o elemento New_Time [0]
    if (copied > 0)                                                // Ok, os dados foram copiados com sucesso
     {
      if (Old_Time != New_Time[0])                                 // Se Old_time for diferente de New_time da barra atual
       {
        IsNewBar=true;                                             
        if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("Temos um newbar aqui",New_Time[0]," oldtime era ",Old_Time);
        Old_Time=New_Time[0];                                      // saving bar time 
        }
  }
else
 {
      Alert("Erro ao copiar dados de tempos históricos, erro =",GetLastError());
      ResetLastError();
      return;
     }
     
// A EA só deve verificar se há novas negociações se tivermos uma nova barra

   if(IsNewBar==false)
     {
      return;
     }
     
 // --- Temos barras suficientes para trabalhar
 
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // se o total de barras for inferior a 60 barras
     {
      Alert("Temos menos de 60 barras!!");
      return;
     }


// --- Definir algumas estruturas MQL5 que usaremos para nossos trades
   MqlDateTime min;
   MqlTick latest_price;      // Para ser usado para obter cotações de preços recentes / mais recentes
   MqlTradeRequest mrequest;  // Para ser usado para enviar nossos pedidos de trading
   MqlTradeResult mresult;    // Para ser usado para obter nossos resultados dos trades
   MqlRates mrate[];          // Para ser usado para armazenar os preços, volumes e spread de cada barra
   ZeroMemory(mrequest);      // Inicialização da estrutura mrequest
   
/*
     Let's make sure our arrays values for the Rates, ADX Values and MA values 
     is store serially similar to the timeseries array
*/

// the rates arrays
   ArraySetAsSeries(mrate,true);
// Array dos valores de DI+
   ArraySetAsSeries(DI_Mais,true);
// Array dos valores de DI-
   ArraySetAsSeries(DI_menos,true);
// Array dos valores de ADX
   ArraySetAsSeries(Valor_ADX,true);
// Array dos valores de BB superior
   ArraySetAsSeries(BB_Sup,true);
// Array dos valores de BB inferior   
   ArraySetAsSeries(BB_Inf,true);
// Array dos valores de BB media   
   ArraySetAsSeries(BB_Med,true);
   
   
// --- Obtenha a última cotação de preço usando a estrutura MQL5 MqlTick

  if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Erro ao obter a última cotação de preço - erro:",GetLastError(),"!!");
      return;
     }
     
     
// --- Obtenha os detalhes das últimas 3 barras
  if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
     {
      Alert("Erro ao copiar taxas / dados de histórico - erro:",GetLastError(),"!!");
      ResetLastError();
      return;
     }
     
 
// --- Copie os novos valores de nossos indicadores para buffers (arrays) usando o identificador

   if(CopyBuffer(Manipulador_ADX,0,0,3,Valor_ADX)<0 || CopyBuffer(Manipulador_ADX,1,0,3,DI_Mais)<0
      || CopyBuffer(Manipulador_ADX,2,0,3,DI_menos)<0)
     {
      Alert("Erro ao copiar buffers do indicador ADX - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }
   if(CopyBuffer(Manipulador_BB,0,0,3,BB_Inf)<0 || CopyBuffer(Manipulador_BB,1,0,3,BB_Sup)<0
      || CopyBuffer(Manipulador_BB,2,0,3,BB_Med)<0)
     {
      Alert("Erro ao copiar o buffer do indicador de BB - erro:",GetLastError());
      ResetLastError();
      return;
     }
     
// --- não temos erros, então continue
// --- Já temos posições abertas?
   bool Buy_opened=false;  // variável para manter o resultado da posição de compra aberta
   bool Sell_opened=false; // variáveis ​​para manter o resultado da posição de venda aberta
   
      if(PositionSelect(_Symbol)==true) // Nos temos posiçoes abertas
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     }
     
     
// Copia o preço de fechamento da barra anterior antes da barra atual, ou seja, Barra 1
   p_open  = mrate[1].open;   // barra 1 preço de abertura
   p_close = mrate[1].close;  // barra 1 preço de fechamento
   p_max   = mrate[1].high;   // barra 1 preço maximo
   p_min   = mrate[1].low;    // barra 1 preço minimo
   
/*
    1. Verificar requisitos para compra:
*/

// --- variáveis ​​do tipo bool para verificar condições de compra

   bool Buy_Condition_1 = (p_min<BB_Inf[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB);           // verifica se a minima ultrapassou a banda inferior e o afastamento das bandas 
//   bool Buy_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max);        // verifica se di+, di- e adx estão menores que filtro adx                    
   bool Buy_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max);        // verifica se di+, di- e adx estão menores que filtro adx                    

// --- Juntando tudo

   if(Buy_Condition_1 && Buy_Condition_2)
     {
         // alguma posição de compra aberta?
         if(Buy_opened)
           {
            Alert("Já temos uma posição de compra!!!");
            return;    // Não abra uma nova posição de compra
           }
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // Execução imediata da ordem
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // Ultimo preço de venda
         mrequest.sl = NormalizeDouble(latest_price.ask - STL*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.ask + STG*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                            // Ativo
         mrequest.volume = Lote;                                               // Numero de lotes
         mrequest.magic = EA_Magic_Number;                                     // Numero Magico da ordem
         mrequest.type = ORDER_TYPE_BUY;                                       // Ordem de compra
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Tipo de execução da ordem
         mrequest.deviation=100;                                               // Desvio do preço atual
         //--- envio da ordem
         if(OrderSend(mrequest,mresult))
         // resultado do codigo
//         if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito
           {
            Alert("Ordem de compra executada com sucesso, ticket: #:",mresult.order,"!!");
           }
         else
           {
            Alert("Falha na ordem de compra, ERRO:",GetLastError());
            ResetLastError();           
            return;
           }
        }
/*
    1. Verificar requisitos para venda:
*/

// --- variáveis ​​do tipo bool para verificar condições de venda

   bool Sell_Condition_1 = (p_max>BB_Sup[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB);        // verifica se a maxima ultrapassou a banda superior e o afastamento das bandas 
//   bool Sell_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max);     // verifica se di+, di- e adx estão menores que filtro adx                    
   bool Sell_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max);     // verifica se di+, di- e adx estão menores que filtro adx                    
    
   //--- Juntando tudo
   if(Sell_Condition_1 && Sell_Condition_2)
     {
         // alguma posição de venda aberta?
         if(Sell_opened)
           {
            Alert("Já temos uma posição de venda!!!");
            return;    // Não abra uma nova posição de venda
           }
         ZeroMemory(mrequest);
         mrequest.action=TRADE_ACTION_DEAL;                                    // Execução imediata da ordem
         mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // Ultimo preço de compra
         mrequest.sl = NormalizeDouble(latest_price.bid + STL*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.bid - STG*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                            // Ativo
         mrequest.volume = Lote;                                               // Numero de lotes
         mrequest.magic = EA_Magic_Number;                                     // Numero Magico da ordem
         mrequest.type= ORDER_TYPE_SELL;                                       // Ordem de venda
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Tipo de execução da ordeme
         mrequest.deviation=100;                                               // Desvio do preço atual
         //--- envio da ordem
         if(OrderSend(mrequest,mresult))
         // resultado do codigo
//         if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito
           {
            Alert("Venda foi feita sucesso, Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("A solicitação do pedido de venda não pôde ser concluída - erro:",GetLastError());
            ResetLastError();
            return;
           }
        }
        return;
        } 
//+------------------------------------------------------------------+
 
Romeu Masselai:
Olá amigos, estou com dificuldades no meu 1º EA, com a estratégia que compra a mercado quando a mínima anterior cruzou a bollinger inferior tendo tbm adx, di+,di- e a distancia das bandas como filtros, e na venda inverte. Ele não esta seguindo a estratégia, e tbm não estou conseguindo colocar um horário limite para ele abrir as posições.

Em relação ao horário, dê uma olhada nessa classe.

Classe para controlar horários de negociação
Classe para controlar horários de negociação
  • www.mql5.com
Essa classe foi projetada com o intuito de ajudar nos horários de negociação, de uma forma simples e centralizada.
 
Vinicius de Oliveira:

Em relação ao horário, dê uma olhada nessa classe.

funcionou muito bem, obrigado, adicionei a classe e incorporei ao EA as alterações porem agora o EA não abre nenhuma posição, aparece 

4807

Manuseio de indicador errado



//+------------------------------------------------------------------+
//|                                                  my_first_ea.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- PARÂMETROS DE ENTRADA

input int      Stop_Loss=30;                     // STOP LOSS
input int      Stop_Gain=10;                     // STOP GAIN
input int      EA_Magic_Number=12345;            // MAGIC NUMBER
input double   Lote=1.0;                         // TAMANHO DO LOTE
sinput string InpStartTime           = "09:02";
sinput string InpEndTime             = "16:06";
sinput string InpClosingTime         = "17:32";

input int      Periodo_ADX=9;                    // PERIODO ADX
input int      adx_atr=1;                        // ATRASO ADX
input int      adx_max=26;                       // FILTRO ADX MAXIMO
input int      Periodo_Bollinger=20;             // PERIODO BOLLINGER
input double   Desvio_Bollinger=2.5;             // DESVIO BANDAS DE BOLLINGER
input double   Afastamento_Maximo_BB=200.0;      // AFASTAMENTO MAXIMO BANDAS DE BOLLINGER

#include <TimeTrade.mqh>



//--- OUTROS PARÂMETROS

int     Manipulador_ADX;                         // HANDLE ADX
int     Manipulador_BB;                          // HANDLE BB
double  DI_Mais[];                               // ARRAY DE ARMAZENAMENTO DI MAIS
double  DI_menos[];                              // ARRAY DE ARMAZENAMENTO DI MENOS
double  Valor_ADX[];                             // ARRAY DE ARMAZENAMENTO ADX
double  BB_Sup[];                                // ARRAY DE ARMAZENAMENTO BB SUPERIOR
double  BB_Inf[];                                // ARRAY DE ARMAZENAMENTO INFERIOR
double  BB_Med[];                                // ARRAY DE ARMAZENAMENTO BB MEDIA
double  p_close;                                 // VARIAVEL PARA ARMAZENAR O VALOR DO FECHAMENTO
double  p_open;                                  // VARIAVEL PARA ARMAZENAR O VALOR DA ABERTURA
double  p_max;                                   // VARIAVEL PARA ARMAZENAR O VALOR DA MAXIMA
double  p_min;                                   // VARIAVEL PARA ARMAZENAR O VALOR DA MINIMA
int     STL;                                     // STOP LOSS
int     STG;                                     // STOP GAIN

CTimeTrade *timeTrade;

//+------------------------------------------------------------------+
//| Função de inicialização do EA                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

if(timeTrade == NULL)
      timeTrade = new CTimeTrade();


   timeTrade.SetTime(InpStartTime, InpEndTime, InpClosingTime);
   timeTrade.TimeAdjustment();

//---
   return(INIT_SUCCEEDED);

  Manipulador_ADX = iADX(_Symbol,PERIOD_CURRENT,Periodo_ADX);
  Manipulador_BB  = iBands(_Symbol,PERIOD_CURRENT,Periodo_Bollinger,0,Desvio_Bollinger,PRICE_CLOSE);
  
  if (Manipulador_ADX < 0 || Manipulador_BB < 0)
   {
      Alert("Erro ao criar handles para indicadores - erro: ",GetLastError(),"!!");
      return(-1);
     }
     //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4
   STL = Stop_Loss;
   STG = Stop_Gain;
   if(_Digits==5 || _Digits==3)
     {
      STL = STL*10;
      STG = STG*10;
     }
   return(0);
  }
//+------------------------------------------------------------------+
//| Função de finalização do EA                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {  
   IndicatorRelease(Manipulador_ADX);             // FINALIZAR HANDLE ADX
   IndicatorRelease(Manipulador_BB);              // FINALIZAR HANDLE BB
   
     if(timeTrade != NULL)
     {
      delete timeTrade;
      timeTrade = NULL;
     }
  }
 
  
//+------------------------------------------------------------------+
//| Função tick EA                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
   if(timeTrade.CheckTimeEndTrade())
     {
      Print("Horário de encerramento de ordens");
      return;
     }

   if(!timeTrade.CheckTimeTrade())
     {
      Print("Horário de parar de abir ordens");
      return;
     }
//--- Verificar se temos candles suficientes
   if(Bars(_Symbol,_Period)<60) // se o total de candles for inferior a 60
     {
      Alert("Temos menos de 60 barras!!");
      return;
     } 
   
   static datetime Old_Time;                                       // Usaremos a variável estática Old_Time para servir o horário do bar.
   datetime New_Time[1];                                           // A cada execução do OnTick verificaremos o tempo de compasso atual com o salvo. 
   bool IsNewBar=false;                                            // Se o tempo da barra não for igual ao tempo economizado, indica que temos um novo tique.
   
   
   int copied = CopyTime(_Symbol,PERIOD_CURRENT,0,1,New_Time);     // Copiando a última barra de tempo para o elemento New_Time [0]
    if (copied > 0)                                                // Ok, os dados foram copiados com sucesso
     {
      if (Old_Time != New_Time[0])                                 // Se Old_time for diferente de New_time da barra atual
       {
        IsNewBar=true;                                             
        if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("Temos um newbar aqui",New_Time[0]," oldtime era ",Old_Time);
        Old_Time=New_Time[0];                                      // saving bar time 
        }
  }
else
 {
      Alert("Erro ao copiar dados de tempos históricos, erro =",GetLastError());
      ResetLastError();
      return;
     }
     
// A EA só deve verificar se há novas negociações se tivermos uma nova barra

   if(IsNewBar==false)
     {
      return;
     }
     
 // --- Temos barras suficientes para trabalhar
 
   int Mybars=Bars(_Symbol,_Period);
   if(Mybars<60) // se o total de barras for inferior a 60 barras
     {
      Alert("Temos menos de 60 barras!!");
      return;
     }


// --- Definir algumas estruturas MQL5 que usaremos para nossos trades
   MqlDateTime min;
   MqlTick latest_price;      // Para ser usado para obter cotações de preços recentes / mais recentes
   MqlTradeRequest mrequest;  // Para ser usado para enviar nossos pedidos de trading
   MqlTradeResult mresult;    // Para ser usado para obter nossos resultados dos trades
   MqlRates mrate[];          // Para ser usado para armazenar os preços, volumes e spread de cada barra
   ZeroMemory(mrequest);      // Inicialização da estrutura mrequest
   
/*
     Let's make sure our arrays values for the Rates, ADX Values and MA values 
     is store serially similar to the timeseries array
*/

// the rates arrays
   ArraySetAsSeries(mrate,true);
// Array dos valores de DI+
   ArraySetAsSeries(DI_Mais,true);
// Array dos valores de DI-
   ArraySetAsSeries(DI_menos,true);
// Array dos valores de ADX
   ArraySetAsSeries(Valor_ADX,true);
// Array dos valores de BB superior
   ArraySetAsSeries(BB_Sup,true);
// Array dos valores de BB inferior   
   ArraySetAsSeries(BB_Inf,true);
// Array dos valores de BB media   
   ArraySetAsSeries(BB_Med,true);
   
   
// --- Obtenha a última cotação de preço usando a estrutura MQL5 MqlTick

  if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Erro ao obter a última cotação de preço - erro:",GetLastError(),"!!");
      return;
     }
     
     
// --- Obtenha os detalhes das últimas 3 barras
  if(CopyRates(_Symbol,_Period,0,3,mrate)<0)
     {
      Alert("Erro ao copiar taxas / dados de histórico - erro:",GetLastError(),"!!");
      ResetLastError();
      return;
     }
     
 
// --- Copie os novos valores de nossos indicadores para buffers (arrays) usando o identificador

   if(CopyBuffer(Manipulador_ADX,0,0,3,Valor_ADX)<0 || CopyBuffer(Manipulador_ADX,1,0,3,DI_Mais)<0
      || CopyBuffer(Manipulador_ADX,2,0,3,DI_menos)<0)
     {
      Alert("Erro ao copiar buffers do indicador ADX - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }
   if(CopyBuffer(Manipulador_BB,0,0,3,BB_Inf)<0 || CopyBuffer(Manipulador_BB,1,0,3,BB_Sup)<0
      || CopyBuffer(Manipulador_BB,2,0,3,BB_Med)<0)
     {
      Alert("Erro ao copiar o buffer do indicador de BB - erro:",GetLastError());
      ResetLastError();
      return;
     }
     
// --- não temos erros, então continue
// --- Já temos posições abertas?
   bool Buy_opened=false;  // variável para manter o resultado da posição de compra aberta
   bool Sell_opened=false; // variáveis ​​para manter o resultado da posição de venda aberta
   
      if(PositionSelect(_Symbol)==true) // Nos temos posiçoes abertas
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;  //It is a Buy
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true; // It is a Sell
        }
     }
     
     
// Copia o preço de fechamento da barra anterior antes da barra atual, ou seja, Barra 1
   p_open  = mrate[1].open;   // barra 1 preço de abertura
   p_close = mrate[1].close;  // barra 1 preço de fechamento
   p_max   = mrate[1].high;   // barra 1 preço maximo
   p_min   = mrate[1].low;    // barra 1 preço minimo
   
/*
    1. Verificar requisitos para compra:
*/

// --- variáveis ​​do tipo bool para verificar condições de compra

   bool Buy_Condition_1 = (p_min<BB_Inf[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB);           // verifica se a minima ultrapassou a banda inferior e o afastamento das bandas                   
   bool Buy_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max);        // verifica se di+, di- e adx estão menores que filtro adx                    

// --- Juntando tudo

   if(Buy_Condition_1 && Buy_Condition_2)
     {
         // alguma posição de compra aberta?
         if(Buy_opened)
           {
            Alert("Já temos uma posição de compra!!!");
            return;    // Não abra uma nova posição de compra
           }
         ZeroMemory(mrequest);
         mrequest.action = TRADE_ACTION_DEAL;                                  // Execução imediata da ordem
         mrequest.price = NormalizeDouble(latest_price.ask,_Digits);           // Ultimo preço de venda
         mrequest.sl = NormalizeDouble(latest_price.ask - STL*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.ask + STG*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                            // Ativo
         mrequest.volume = Lote;                                               // Numero de lotes
         mrequest.magic = EA_Magic_Number;                                     // Numero Magico da ordem
         mrequest.type = ORDER_TYPE_BUY;                                       // Ordem de compra
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Tipo de execução da ordem
         mrequest.deviation=100;                                               // Desvio do preço atual
         //--- envio da ordem
         if(OrderSend(mrequest,mresult))
         // resultado do codigo
//         if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito
           {
            Alert("Ordem de compra executada com sucesso, ticket: #:",mresult.order,"!!");
           }
         else
           {
            Alert("Falha na ordem de compra, ERRO:",GetLastError());
            ResetLastError();           
            return;
           }
        }
/*
    1. Verificar requisitos para venda:
*/

// --- variáveis ​​do tipo bool para verificar condições de venda

   bool Sell_Condition_1 = (p_max>BB_Sup[0]) && ((BB_Sup[0] - BB_Inf[0]) < Afastamento_Maximo_BB);        // verifica se a maxima ultrapassou a banda superior e o afastamento das bandas 
//   bool Sell_Condition_2 = ((DI_Mais[adx_atr] && DI_menos[adx_atr] && Valor_ADX[adx_atr]) < adx_max);     // verifica se di+, di- e adx estão menores que filtro adx                    
   bool Sell_Condition_2 = (DI_Mais[adx_atr] < adx_max && DI_menos[adx_atr] < adx_max && Valor_ADX[adx_atr] < adx_max);     // verifica se di+, di- e adx estão menores que filtro adx                    
    
   //--- Juntando tudo
   if(Sell_Condition_1 && Sell_Condition_2)
     {
         // alguma posição de venda aberta?
         if(Sell_opened)
           {
            Alert("Já temos uma posição de venda!!!");
            return;    // Não abra uma nova posição de venda
           }
         ZeroMemory(mrequest);
         mrequest.action=TRADE_ACTION_DEAL;                                    // Execução imediata da ordem
         mrequest.price = NormalizeDouble(latest_price.bid,_Digits);           // Ultimo preço de compra
         mrequest.sl = NormalizeDouble(latest_price.bid + STL*_Point,_Digits); // Stop Loss
         mrequest.tp = NormalizeDouble(latest_price.bid - STG*_Point,_Digits); // Take Profit
         mrequest.symbol = _Symbol;                                            // Ativo
         mrequest.volume = Lote;                                               // Numero de lotes
         mrequest.magic = EA_Magic_Number;                                     // Numero Magico da ordem
         mrequest.type= ORDER_TYPE_SELL;                                       // Ordem de venda
         mrequest.type_filling = ORDER_FILLING_FOK;                            // Tipo de execução da ordeme
         mrequest.deviation=100;                                               // Desvio do preço atual
         //--- envio da ordem
         if(OrderSend(mrequest,mresult))
         // resultado do codigo
//         if(mresult.retcode==10009 || mresult.retcode==10008) //A solicitação foi concluída ou o pedido foi feito
           {
            Alert("Venda foi feita sucesso, Ticket#:",mresult.order,"!!");
           }
         else
           {
            Alert("A solicitação do pedido de venda não pôde ser concluída - erro:",GetLastError());
            ResetLastError();
            return;
           }
        }
        return;
        } 
//+------------------------------------------------------------------+
 
Romeu Masselai:

funcionou muito bem, obrigado, adicionei a classe e incorporei ao EA as alterações porem agora o EA não abre nenhuma posição, aparece 

4807

Manuseio de indicador errado



Bom dia!


- Em OnInit(), esse return(INIT_SUCCEEDED) tem que ir lá pro final, no lugar de return(0), senão os comandos seguintes não são executados.

- Essa verificação da quantidade de barras disponíveis no histórico está em duplicidade (desnecessário).

- Nessas verificações dos horários, o timeTrade.CheckTimeEndTrade() é útil caso você queira encerrar as posições abertas naquele horário. Então, se for utilizar, inclua um código / função para encerrar posições.

 
Vinicius de Oliveira:

Bom dia!


- Em OnInit(), esse return(INIT_SUCCEEDED) tem que ir lá pro final, no lugar de return(0), senão os comandos seguintes não são executados.

- Essa verificação da quantidade de barras disponíveis no histórico está em duplicidade (desnecessário).

- Nessas verificações dos horários, o timeTrade.CheckTimeEndTrade() é útil caso você queira encerrar as posições abertas naquele horário. Então, se for utilizar, inclua um código / função para encerrar posições.

Obrigado Vinicius, ficou perfeito, vc sabe me dizer se no forum existe alguma classe já pronta pra gerenciamento de risco com meta de lucro ou perdas?
 
Romeu Masselai:
Obrigado Vinicius, ficou perfeito, vc sabe me dizer se no forum existe alguma classe já pronta pra gerenciamento de risco com meta de lucro ou perdas?

Opa, Romeu! Bom que deu certo! 🤝


No fórum existem algumas sugestões de funções para essa finalidade, que com pequenos ajustes, devem lhe atender, como nesse tópico (veja correção da função inicial no comentário #3).


Essa busca retorna outros exemplos que podem ser úteis.


... Lembrando também que, caso não encontre um código da forma que você esperava, há sempre a possibilidade de registrar a sua encomenda no Freelance.  👍

Função para Profit do dia
Função para Profit do dia
  • 2020.05.30
  • www.mql5.com
Boa noite pessoal, criei uma função para obter o Ganho/ Perda do dia, porem não estou conseguindo o resultado que preciso, usando o HistorySelect...
 

Boa tarde @Romeu Masselai!


Você não testou o código que lhe sugeri acima e está abrindo vários tópicos com a mesma dúvida, né? 😃


Teste o código (com pequenas alterações) e dê algum retorno: 👍


//--- Número de vitórias:
int WinNumber()
  {
   int Res = 0;
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));

   if(HistorySelect(time_start,TimeCurrent()))
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) > 0.0)
            Res ++;
        }

   return(Res);
  }



//--- Número de perdas:
int LossNumber()
  {
   int Res = 0;
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));

   if(HistorySelect(time_start,TimeCurrent()))
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) < 0.0)
            Res ++;
        }

   return(Res);
  }



//--- A versão original da função retorna o resultado do dia (lucro ou prejuízo):
double Profit()
  {
   double Res = 0.0;
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));

   if(HistorySelect(time_start,TimeCurrent()))
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == MAGICNUM && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol)
            Res += HistoryDealGetDouble(Ticket, DEAL_PROFIT);
        }

   return(Res);
  }


Acho que time_start pode ser informado também assim (mais simples):

datetime time_start = iTime(_Symbol, PERIOD_D1, 0);



Para agilizar, as funções podem ser unificadas.

 
Vinicius de Oliveira:

Boa tarde @Romeu Masselai!


Você não testou o código que lhe sugeri acima e está abrindo vários tópicos com a mesma dúvida, né? 😃


Teste o código (com pequenas alterações) e dê algum retorno: 👍



Acho que time_start pode ser informado também assim (mais simples):



Para agilizar, as funções podem ser unificadas.

Boa tarde, muito obrigado pela ajuda Vinicius, incorporei a função no EA, mas devo ter feito algo errado, ele compila sem erros mas o EA não faz o que é pra fazer

sinput   group    "------ Gerenciamento Financeiro $"
input int      maxloss               = 2;        // LIMITE DE LOSS DIARIO
input int      maxgain               = 10;       // LIMITE DE GAIN DIARIO
   bool Buy_Condition_3 = ((WinNumber() <= maxgain) && (LossNumber() >= maxloss));
//--- Número de vitórias:
int WinNumber()
  {
   int Res = 0;
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));

   if(HistorySelect(time_start,TimeCurrent()))
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == EA_Magic_Number && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) > 0.0)
            Res ++;
        }
   return(Res);
  }



//--- Número de perdas:
int LossNumber()
  {
   int Res = 0;
   datetime time_start = (datetime) (86400*(((ulong)TimeCurrent())/86400));

   if(HistorySelect(time_start,TimeCurrent()))
      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         const ulong Ticket = HistoryDealGetTicket(i);

         if(HistoryDealGetInteger(Ticket, DEAL_MAGIC) == EA_Magic_Number && HistoryDealGetString(Ticket, DEAL_SYMBOL) == _Symbol && HistoryDealGetDouble(Ticket, DEAL_PROFIT) < 0.0)
            Res ++;
        }
   return(Res);
  }
 
Romeu Masselai:

Boa tarde, muito obrigado pela ajuda Vinicius, incorporei a função no EA, mas devo ter feito algo errado, ele compila sem erros mas o EA não faz o que é pra fazer

Olá Romeu!


Corrija a condição para:

bool Buy_Condition_3 = ((WinNumber() <= maxgain) && (LossNumber() <= maxloss));

... E dê um retorno ...

 
Vinicius de Oliveira:

Olá Romeu!


Corrija a condição para:

... E dê um retorno ...

Aparentemente funcionou :)  vou testar mais afundo e com tempo, muito obrigado pela sua ajuda, estava tão pilhado nisso, que não percebi esse detalhe, por isso é bom um olhar externo.

Razão: