Limitar robô por horário e/ou numero de operções. - página 2

 
Willian De Caldas Leite:

Se te ajudar eu uso esse padrao nos meus EA.



Muito legal!

Desculpe a ignorância (e é muita, estou começando agora :), qual o comando para usar no EA? Você usa no evento OnTrade()?

Seria legal se tivesse uma biblioteca assim para linkar no gerador de experts (achei uma legal - TradeState - mas também não sei usar :( .

Estou testando (para aprender) em um EA "pronto", mas o bendito ignora totalmente meu comando. Também tentei ExtExpert.Close(), mas é método privado da CExpert e o compilador não gostou da ideia...

Minha gambiarra:

// para permitir fechamento de posições
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>  
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
CSymbolInfo    m_symbol;                     // symbol info object



// da warning de conversao implicita, mas acredito que o erro nao seja este
input datetime Hora_Inicio ="09:05"; //Hora limite para abrir posicoes
input datetime Hora_Limite ="16:00"; // Hora limite para operar
input datetime Hora_Fim="17:00"; //Fecha posições abertas
// A encrenca esta aqui: nao obedece a limitacao de horario :(
void OnTrade()
  {
// se estiver dentro do horario de negociacao, opera normalmente
   if((TimeCurrent())>=Hora_Inicio && (TimeCurrent())<=Hora_Limite)
     {
      ExtExpert.OnTrade();
     }
// se ja tiver passado do horario e ainda tiver posicao aberta, fecha todas   
   if((TimeCurrent())>=Hora_Fim && PositionsTotal()>0)
     {
      for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions
         m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
     }
  }
 

 

            Olá, como vai? Quebrando a cabeça com as datas?


           Você precisa preparar as variáveis fazendo o tratamento com a função:

               

            void sDATA(){


            MqlDateTime sTimeKey, sTimeOpen;

            TimeToStruct(StringToTime(sTimeKey_P),sTimeKey);     // sTimeKey_P - String Contendo a informação de data // StimeKey - Variável que receberá as informações


            }

             

       *O erro no seu código é que vc está tentando comparar diretamente, sem fazer o tratamento.

 

Nelson, obrigado pela atenção.

Fiquei lutando com a comparação de strings x datas e desisti (por enquanto ;)

Tentei usar o código do Willian, mas parece que não funcionou. Aumentei a margem dos horários para ficar mais fácil de visualizar:

input string inicio="10:30"; //Horario de inicio(entradas);
input string termino="15:00"; //Horario de termino(entradas);
input string fechamento="15:30"; //Horario de fechamento(entradas);

e alterei o meu OnTrade:

void OnTrade()
  {


// se estiver dentro do horario de negociacao, opera normalmente
   if(HorarioEntrada())
     {
      ExtExpert.OnTrade();
     }

// se ja tiver passado do horário e ainda tiver posicao aberta, fecha todas   
   if(HorarioFechamento() && PositionsTotal()>0)
     {
      for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of current positions
         m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
     }
  }

No entanto ele continua negociando nos períodos "proibidos":

Gráfico do testador

 
Anderson Almeida:


Olá,

tres observações:

1) O evento correto para efetuar trades seria on OnTick.

2) O seu teste de data só vai funcionar no primeiro dia do backtest, pois datetime é dia e hora e do jeito que você fez o dia está fixo. A cada novo dia tem que ajustar novamente as datas.

3) PosistionsTotal() é a quantidade de posições abertas no MT5, ou seja de todos EA(s) e todas a operações manuais que você fez. Você quer mesmo fechar tudo?


int OnInit()
{
input string inicio="10:30"; //Horario de inicio(entradas);
input string termino="15:00"; //Horario de termino(entradas);
input string fechamento="15:30"; //Horario de fechamento(entradas);

datetime             hrInicio,hrFim,hrEncerramento;
}
OnTick()
{

if (NovoDia())
{
      hrInicio=StringToTime(inicio);
      hrFim=StringToTime(termino);
      hrEncerramento=StringToTime(fechamento);
}
if(TimeCurrent()>=hrInicio&& TimeCurrent()<=hrFim)
{

}

if(TimeCurrent()>hrEncerramento && PositionsTotal()>0)
{

}

}
 
Rogerio Giannetti Torres:

Olá,

tres observações:

1) O evento correto para efetuar trades seria on OnTick.


Obrigado pela atenção, Rogério.

Como eu faria para controlar o evento de negociação dentro do ontick? Tem como "cancelar" o sinal do indicador?

2) O seu teste de data só vai funcionar no primeiro dia do backtest, pois datetime é dia e hora e do jeito que você fez o dia está fixo. A cada novo dia tem que ajustar novamente as datas.

Ótima observação (não tinha me ligado nesse detalhe). Mas acho que código do Willian cuida dessa parte (ou não)? Pelo que entendi da funçâo (trecho abaixo), ele extrai e compara apenas horas e minutos, pouco importando o dia:

bool HorarioEntrada()
  {
   TimeToStruct(TimeCurrent(),horario_atual);

   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;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool HorarioFechamento()
  {
   TimeToStruct(TimeCurrent(),horario_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;
  }//--- fim da verificacao de datas


3) PosistionsTotal() é a quantidade de posições abertas no MT5, ou seja de todos EA(s) e todas a operações manuais que você fez. Você quer mesmo fechar tudo?


Querer eu não quero, mas foi o jeito que eu achei pronto para começar a testar :)

Como poderia ser o código para fechar só as posições abertas pelo expert para o símbolo em questão?


Finalmente (se não for pedir muito), alguém poderia postar ou indicar um código de expert básico (de preferência feito com o gerador do mt5) que tenha essa bendita funcionalidade? É super frustrante não conseguir fazer nenhum teste minimamente realista com daytrade e não entender como codificar algo aparentemente tão simples.

 

Descobri a solução, nem precisa programar!

No gerador de experts, tem um módulo de filtro intradiário. Eu já tinha visto, mas achava que ele não limitava os trades.

O truque é ajeitar o badhoursofday (horas ruins do dia).

Ele mapeia um número binário com 24 bits, cada um correspondendo a uma hora do dia, sendo 1 para não negociar, e 0 liberado, na sequência (24 23 22... 01 00)

Então, por exemplo, para ativar entre as 10 e as 15h59: 111111110000001111111111.

Convertendo para decimal: 16712703.

negociando das 10 às 15h59


Tenho certeza que os Srs. têm uma solução mais elegante (com controle de minutos, por exemplo), mas para mim já é um ótimo começo :D

 
an.hernandez79:

Boa tarde pessoal. Estou iniciando os estudos em MQL5, ou seja, não sei nada. Alguma coisa já aprendi. Já consegui criar um indicador simples. Estou baixando robôs gratuitos e fazendo testes, abrindo os códigos para tentar entender. A minha questão é, o que preciso inserir no código de um robô para que acrescente parâmetros de entrada nele para restringir a operação do mesmo por quantidades de ordens no dia? E para restringir por horário? Ou ainda restringir a uma perda por dia?

Obrigado!

Olá,  an.hernandez79!

Também sou iniciante. Assim como você, eu busco controlar diversos aspectos no meu EA, duração das posições, número de posições, máximo de perdas etc. Para as perdas, que eu não vi resposta acima, eu utilizo essa função:

   
int PerdasDia(void)
  {
   MqlRates rt[1];
   if(CopyRates(_Symbol,PERIOD_D1,0,1,rt)!=1)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return(10);
     }
//--- 
      //--- select history for access
      HistorySelect(rt[0].time,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         //if(profit>0.0)
         //   break;
         if(profit<0.0)
            losses++;
        }
      //---
   return(losses);
  }

Espero ter ajudado!

 
OLA BAO TARDE GOSTARIA DE SABER SE AO EFETUAR AS OPERAÇOES DE ENTRADA E FECHAMENTO E DATA SE EU PRESIZO ESTAR COM MEU COMPUTADOR LIGADO OU POSSO FAZER TODO PROSESSO E IR TRABALHAR OBRIGADO DESCULP PELA IGUINORANCIA AGUARDO RESPOSTA.
 
detestopecimismo BORGES:
OLA BAO TARDE GOSTARIA DE SABER SE AO EFETUAR AS OPERAÇOES DE ENTRADA E FECHAMENTO E DATA SE EU PRESIZO ESTAR COM MEU COMPUTADOR LIGADO OU POSSO FAZER TODO PROSESSO E IR TRABALHAR OBRIGADO DESCULP PELA IGUINORANCIA AGUARDO RESPOSTA.
Se você usar um robô e alugar um servidor virtual para o robô rodar, vc poderá operar sem precisar estar com seu computador ligado e sem precisar acompanhar a operação ... mas tem que confiar muito no robô pra deixar ele operando sem acompanhar.
 
Consegui seguindo esse video onde o autor mostra passo a passo como controlar limites de horários de negociação: https://www.youtube.com/watch?v=4Xjw2_aua8o
Razão: