Gerenciamento de risco, limite diário de operações

ROMEU MASSELAI  

Bom dia rapazes, sou iniciante, e estou com dificuldades pra colocar um limite diário de operações com lucro ou com prejuízo, esse limite o usuário define nos parâmetros, e quando o EA atinge o numero de operações com LUCRO ou com PREJUIZO, o EA só volta a operar no dia seguinte. 

//+------------------------------------------------------------------+
//|                                                  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"
//---
#include <TimeTrade.mqh>
//+------------------------------------------------------------------+
//| Parâmetros de Entrada                                            |
//+------------------------------------------------------------------+
sinput group "----- Parâmetros de Negociação"
input int      Stop_Loss             = 115;      // STOP LOSS
input int      Stop_Gain             = 25;       // STOP GAIN
input int      EA_Magic_Number       = 12345;    // MAGIC NUMBER
input double   Lote                  = 1.0;      // TAMANHO DO LOTE
//---
sinput   group    "------ Horários de Negociação [hh:mm]"
sinput string  InpStartTime          = "09:10";  // ABRIR ORDENS
sinput string  InpEndTime            = "16:00";  // PARAR ABRIR ORDENS
sinput string  InpClosingTime        = "17:00";  // ENCERRAR ORDENS ABERTAS
//---
sinput   group    "------ Parametros dos Indicadores [hh:mm]"
input int      Periodo_ADX           = 36;       // PERIODO ADX
input int      adx_atr               = 0;        // ATRASO ADX
input int      adx_max               = 37;       // FILTRO ADX MAXIMO
input int      Periodo_Bollinger     = 11;       // PERIODO BOLLINGER
input double   Desvio_Bollinger      = 1.8;      // DESVIO BANDAS DE BOLLINGER
input double   Afastamento_Maximo_BB = 370.0;    // AFASTAMENTO MAXIMO BANDAS DE BOLLINGER
//---
sinput   group    "------ Gerenciamento Financeiro $"
input int      maxloss               = 2;        // LIMITE DE LOSS DIARIO
input int      maxgain               = 10;       // LIMITE DE GAIN DIARIO

//--- 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
int     closs = 0;                               // CONTADOR LOSS
int     cgain = 0;                               // CONTADOR 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();
   
//---

  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);
      }
   STL = Stop_Loss;
   STG = Stop_Gain;
   if(_Digits==5 || _Digits==3)
      {
      STL = STL*10;
      STG = STG*10;
      }
    return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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 ontick                                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
  ChartIndicatorAdd(0,0,Manipulador_BB);
  
  if(timeTrade.CheckTimeEndTrade())
     {
      Print("Horário de encerramento de ordens");
      return;
     }

   if(!timeTrade.CheckTimeTrade())
     {
      Print("Horário de parar de abir ordens");
      return;
     }

   if(Bars(_Symbol,_Period)<60)                                    // verificar se temos 60 candles
     {
      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;
     }
 
   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

   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

// 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 dados 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 

   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,2,0,3,BB_Inf)<0 || CopyBuffer(Manipulador_BB,1,0,3,BB_Sup)<0
      || CopyBuffer(Manipulador_BB,0,0,3,BB_Med)<0)
     {
      Alert("Erro ao copiar o buffer do indicador de BB - erro:",GetLastError());
      ResetLastError();
      return;
     }
     
// 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)                                                                                       //temos posiçoes abertas
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_opened=true;                                                                                                     // Posição de compra
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_opened=true;                                                                                                    // Posição de venda
        }
     }
        
// 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
   
// Verificar requisitos para compra:

   bool Buy_Condition_1 = (p_min<BB_Inf[1]) && ((BB_Sup[1] - BB_Inf[1]) < 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                    
   bool Buy_Condition_3 = ((cgain < maxgain) && (closs > maxloss));
   
// Juntando tudo

   if(Buy_Condition_1 && Buy_Condition_2)
     {
      if(Buy_Condition_3)
        {

         if((Buy_opened) || (Sell_opened))                                                                                    // alguma posição de compra aberta?
           {
            Alert("Já temos uma posição!!!");
            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
          
         if(OrderSend(mrequest,mresult))                                                                                      // envio da ordem
           {
            Alert("Ordem de compra executada com sucesso, ticket: #:",mresult.order,"!!");
           }
         else
           {
            Alert("Falha na ordem de compra, ERRO:",GetLastError());
            ResetLastError();           
            return;
           }
        }
       }
// Verificar requisitos para venda:

   bool Sell_Condition_1 = (p_max>BB_Sup[1]) && ((BB_Sup[1] - BB_Inf[1]) < Afastamento_Maximo_BB);                          // verifica se a maxima ultrapassou a banda superior e o afastamento das bandas 
   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                    
   bool Sell_Condition_3 = ((cgain < maxgain) && (closs > maxloss));
   
// Juntando tudo
   
   if(Sell_Condition_1 && Sell_Condition_2)
     {
      if(Buy_Condition_3)
        {
        
         if((Buy_opened) || (Sell_opened))                                                                                  // alguma posição de venda aberta?
           {
            Alert("Já temos uma posição!!!");
            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

         if(OrderSend(mrequest,mresult))                                                                                    // envio da ordem
           {
            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;
        }
}

//+------------------------------------------------------------------+
//| Gerenciamento de Risco                                           |
//+------------------------------------------------------------------+

void OnTrade()
{

   HistorySelect(iTime(_Symbol, PERIOD_D1, 0), TimeCurrent());
      ulong t= HistoryDealGetTicket(0);
      double p= HistoryDealGetDouble(t, DEAL_SWAP)
         +HistoryDealGetDouble(t, DEAL_PROFIT)
         +HistoryDealGetDouble(t, DEAL_COMMISSION);
      if (p > 0)
        {
         cgain=cgain+1;
        }
      if (p < 0)
        {
        closs=closs+1;
        }
  }

 
martinspdaniel  
Ana Leticia:

Bom dia rapazes, sou iniciante, e estou com dificuldades pra colocar um limite diário de operações com lucro ou com prejuízo, esse limite o usuário define nos parâmetros, e quando o EA atinge o numero de operações com LUCRO ou com PREJUIZO, o EA só volta a operar no dia seguinte. 

Olá Ana, também estou com a mesma dificuldade, conseguiu evoluir? 
Razão: