ROBO ABRINDO ORDENS INFINITAS

Isac Trading  

Olá pessoal, sou novo aqui, espero que estejam todos bem,  estou com um problema neste EA baseado em Bandas de Bollinger, sempre que o preço rompe a banda superior ou inferior ele abre varias posições consecutivas até zerar o saldo.

Estou trabalhando com PostionsTotal...

Alguém poderia me ajudar ?

//+------------------------------------------------------------------+
//|                                           Bandas de Bolinger.mq5 |
//|                           
//+------------------------------------------------------------------+
#property copyright "Isac Teixiera"
#property link      "Isactrading@gmail.comm"
#property version   "1.00"

// Inclusão de bibliotecas utilizadas
#include <Trade/Trade.mqh>
#include <Trade/SymbolInfo.mqh>
CTrade trade;

input group              "Configurações gerais"
input ulong              Magic          = 123456;      // Número mágico
input group              "Configurações operacionais"
input double             SL             = 0.0;         // Stop Loss
input double             TP             = 0.0;         // Take Profit
input double             Volume         = 1;           // Volume
input group              "Configurações do indicador"
input int                Periodo        = 20;          // Período
input double             Desvio         = 2;           // Desvio
input int                Deslocamento   = 0;           // Deslocar
input ENUM_APPLIED_PRICE Preco          = PRICE_CLOSE; // Preço Aplicado
input group              "Configurações de horários"
input string             inicio         = "09:00";     // Horário de Início (entradas)
input string             termino        = "17:00";     // Horário de Término (entradas)
input string             fechamento     = "17:30";     // Horário de Fechamento (posições)
input group              "Risco Diário"
input double             LimiteGain     = 100;    // Limite de Gain diário financeiro
input double             LimiteLoss     = 50;     // Limite de Loss diário financeiro

int         handle;
string      shortname;

CTrade      negocio; // Classe responsável pela execução de negócios
CSymbolInfo simbolo; // Classe responsãvel pelos dados do ativo

// Estruturas de tempo para manipulação de horários
MqlDateTime horario_inicio, horario_termino, horario_fechamento, horario_atual;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   trade.SetExpertMagicNumber(Magic);
//---

// Definição do símbolo utilizado para a classe responsável
   if(!simbolo.Name(_Symbol))
     {
      printf("Ativo Inválido!");
      return INIT_FAILED;
     }

// Criação dos manipulador
   handle = iBands(_Symbol, _Period, Periodo, Deslocamento, Desvio, Preco);

// Verificação do resultado da criação dos manipuladores
   if(handle == INVALID_HANDLE)
     {
      Print("Erro na criação dos manipuladores");
      return INIT_FAILED;
     }

   if(!ChartIndicatorAdd(0, 0, handle))
     {
      Print("Erro na adição do indicador ao gráfico");
      return INIT_FAILED;
     }

   shortname = ChartIndicatorName(0, 0, ChartIndicatorsTotal(0, 0)-1);
//---

// Criação das structs de tempo
   TimeToStruct(StringToTime(inicio), horario_inicio);
   TimeToStruct(StringToTime(termino), horario_termino);
   TimeToStruct(StringToTime(fechamento), horario_fechamento);




// Verificação de inconsistências nos parâmetros de entrada
   if(horario_inicio.hour > horario_termino.hour || (horario_inicio.hour == horario_termino.hour && horario_inicio.min > horario_termino.min))
     {
      printf("Parâmetros de Horário inválidos!");
      return INIT_FAILED;
     }

// Verificação de inconsistências nos parâmetros de entrada
   if(horario_termino.hour > horario_fechamento.hour || (horario_termino.hour == horario_fechamento.hour && horario_termino.min > horario_fechamento.min))
     {
      printf("Parâmetros de Horário inválidos!");
      return INIT_FAILED;
     }

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   ChartIndicatorDelete(0, 0, shortname);

// Motivo da desinicialização do EA
   printf("Deinit reason: %d", reason);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
// Atualização dos dados do ativo
   if(!simbolo.RefreshRates())
      return;

// EA em horário de entrada em novas operações
   if(HorarioEntrada())
     {
      // EA não está posicionado
      if(SemPosicao())
        {
         // Verificar estratégia e determinar compra ou venda
         int resultado = Sinal();

         // Estratégia indicou compra
         if(resultado  == -1)
            Compra();
         // Estratégia indicou venda
         if(resultado  == 1)
            Venda();
        }
     }

// EA em horário de fechamento de posições abertas
   if(HorarioFechamento())
     {
      // EA está posicionado, fechar posição
      if(!SemPosicao())
         Fechar();
     }

  }
//+------------------------------------------------------------------+
//| Checar se horário atual está dentro do horário de entradas       |
//+------------------------------------------------------------------+
bool HorarioEntrada()
  {
   TimeToStruct(TimeCurrent(), horario_atual); // Obtenção do horário atual

// Hora dentro do horário de entradas
   if(horario_atual.hour >= horario_inicio.hour && horario_atual.hour <= horario_termino.hour)
     {
      // Hora atual igual a de início
      if(horario_atual.hour == horario_inicio.hour)
         // Se minuto atual maior ou igual ao de início => está no horário de entradas
         if(horario_atual.min >= horario_inicio.min)
            return true;
      // Do contrário não está no horário de entradas
         else
            return false;

      // Hora atual igual a de término
      if(horario_atual.hour == horario_termino.hour)
         // Se minuto atual menor ou igual ao de término => está no horário de entradas
         if(horario_atual.min <= horario_termino.min)
            return true;
      // Do contrário não está no horário de entradas
         else
            return false;

      // Hora atual maior que a de início e menor que a de término
      return true;
     }

// Hora fora do horário de entradas
   return false;
  }
//+------------------------------------------------------------------+
//| Checar se horário atual está dentro do horário de fechamento     |
//+------------------------------------------------------------------+
bool HorarioFechamento()
  {
   TimeToStruct(TimeCurrent(), horario_atual); // Obtenção do horário atual

// Hora dentro do horário de fechamento
   if(horario_atual.hour >= horario_fechamento.hour)
     {
      // Hora atual igual a de fechamento
      if(horario_atual.hour == horario_fechamento.hour)
         // Se minuto atual maior ou igual ao de fechamento => está no horário de fechamento
         if(horario_atual.min >= horario_fechamento.min)
            return true;
      // Do contrário não está no horário de fechamento
         else
            return false;

      // Hora atual maior que a de fechamento
      return true;
     }

// Hora fora do horário de fechamento
   return false;
  }
//+------------------------------------------------------------------+
//| Realizar compra com parâmetros especificados por input           |
//+------------------------------------------------------------------+
void Compra()
  {
   double price = simbolo.Ask();
   double stoploss = simbolo.NormalizePrice(price - SL); // Cálculo normalizado do stoploss
   double takeprofit = simbolo.NormalizePrice(price + TP); // Cálculo normalizado do takeprofit
   negocio.Buy(Volume, NULL, price, stoploss, takeprofit, "Compra"); // Envio da ordem de compra pela classe responsável
  }
//+------------------------------------------------------------------+
//| Realizar venda com parâmetros especificados por input            |
//+------------------------------------------------------------------+
void Venda()
  {
   double price = simbolo.Bid();
   double stoploss = simbolo.NormalizePrice(price + SL); // Cálculo normalizado do stoploss
   double takeprofit = simbolo.NormalizePrice(price - TP); // Cálculo normalizado do takeprofit
   negocio.Sell(Volume, NULL, price, stoploss, takeprofit, "Venda"); // Envio da ordem de compra pela classe responsável
  }
//+------------------------------------------------------------------+
//| Fechar posição aberta                                            |
//+------------------------------------------------------------------+
void Fechar()
  {
// Verificação de posição aberta
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(!PositionSelectByTicket(ticket))
         continue;
      if(PositionGetString(POSITION_SYMBOL)!=_Symbol || PositionGetInteger(POSITION_MAGIC)!=Magic)
         continue;
      negocio.PositionClose(ticket);
     }
  }
//+------------------------------------------------------------------+
//| Verificar se há posição aberta                                   |
//+------------------------------------------------------------------+
bool SemPosicao()
  {
   int total = PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(!PositionSelectByTicket(ticket))
         continue;
      if(PositionGetString(POSITION_SYMBOL)!=_Symbol || PositionGetInteger(POSITION_MAGIC)!=Magic)
         continue;
      return false;
     }

   return true;
  }
//+------------------------------------------------------------------+
//| Estratégia                                                       |
//+------------------------------------------------------------------+
int Sinal()
  {
   double superior[], inferior[];

   ArraySetAsSeries(superior, true);
   ArraySetAsSeries(inferior, true);
   CopyBuffer(handle, 1, 0, 2, superior);
   CopyBuffer(handle, 2, 0, 2, inferior);

   double close_atual = iClose(_Symbol, _Period, 0);
   double close_anterior = iClose(_Symbol, _Period, 1);

   if(close_anterior >= inferior[1] && close_atual < inferior[0])
      return 1;
   if(close_anterior <= superior[1] && close_atual > superior[0])
      return -1;

   return 0;
  }

//Se o limite diário de gain ou loss for atingido encerra ordens ou posições em aberto
bool CheckLimites()
  {

   if(LimiteGain > 0 && GetSaldoFinanceiro() >= LimiteGain)
     {
      Fechar();
      Print("Limite de Gain diário batido.");
      return true;
     }

   if(LimiteLoss > 0 && GetSaldoFinanceiro() <= (LimiteLoss*-1))
     {
      Fechar();
      Print("Limite de Loss diário batido.");
      return true;
     }

   return false;
  }
//+------------------------------------------------------------------+


Gratidão.

Desde já agradeço a todos.

Ricardo Rodrigues Lucca  
Isac Trading:

Olá pessoal, sou novo aqui, espero que estejam todos bem,  estou com um problema neste EA baseado em Bandas de Bollinger, sempre que o preço rompe a banda superior ou inferior ele abre varias posições consecutivas até zerar o saldo.

Estou trabalhando com PostionsTotal...

Alguém poderia me ajudar ?


Gratidão.

Desde já agradeço a todos.

utilize a mesma variavel do tipo CTrade. Nao ha necessidade de ter duas uma chamada negocio e outra trade. Na ultima voce setou o magic number na ultima nao. Sendo assim, todas as suas execucoes foram feitas sem o numero magico que a funcao SemPosicao() verifica e como nao acha uma posicao com o numero magico devolve que esta okay pra abrir posicao.
Razão: