Valores high e low do primeiro candle do dia

 

Olá amigos, 

Desta vez to precisando de uma ajudinha....

No gráfico de 6 minutos, consigo pegar com meu EA os valores high e low do primeiro candle do dia atual sem problema algum quando inicio o EA antes de abrir o pregão.

O problema está quando ativo o EA no decorrer do dia, dai não estou conseguindo pegar o valor do primeiro candle do dia de forma simples. Fiz uma instrução enorme e nada funcional: converto em segundos, dai comparo a hora atual com 9:00h (abertura), subtraio, multiplico por minutos, divido por qtd de candles, para depois saber quantos candles para usar no CopyRates e contar para trás ... enfim... ficou um negócio complexo e nada funcional.

Deve ter alguma forma mais simples de pegar os valores high e low do primeiro candle independente da hora que o EA foi ativado, mas eu não consegui.

Se alguém tiver ai alguma dica ou código para me ajudar, agradeço muito.

 
Ruy Christian Hoffmann:

Olá amigos, 

Desta vez to precisando de uma ajudinha....

No gráfico de 6 minutos, consigo pegar com meu EA os valores high e low do primeiro candle do dia atual sem problema algum quando inicio o EA antes de abrir o pregão.

O problema está quando ativo o EA no decorrer do dia, dai não estou conseguindo pegar o valor do primeiro candle do dia de forma simples. Fiz uma instrução enorme e nada funcional: converto em segundos, dai comparo a hora atual com 9:00h (abertura), subtraio, multiplico por minutos, divido por qtd de candles, para depois saber quantos candles para usar no CopyRates e contar para trás ... enfim... ficou um negócio complexo e nada funcional.

Deve ter alguma forma mais simples de pegar os valores high e low do primeiro candle independente da hora que o EA foi ativado, mas eu não consegui.

Se alguém tiver ai alguma dica ou código para me ajudar, agradeço muito.

Como eu faria:

- Usaria a estutura MqlRates;

MqlRates                candle[];

- utilizaria o ArraySetAsSeries na variavel candle[];

- Criaria uma variável int para contar o numero de barras (conta_barras);

- Criaria variáveis do tipo static para armazenar os valores OHLC do primeiro candle;

- Apos verificar a formação do 2o candle, eu armazenaria os dados do 1o candle nas variaveis static. Dai poderia utiliza-las a qualquer momento.

- A logica ficaria mais ou menos assim:

if(conta_barras==2){variavel_static_1=candle[1].open;variavel_static_2=candle[1].high;variavel_static_3=candle[1].low;variavel_static_4=candle[1].close;}

OBSERVAÇÃO: Pensei isto em face do que escreveu. Precisa testar. De qualquer forma, acredito que ocupe um numero menor de linhas de código e que vai funcionar.

Para verificar a formação de nova barra, caso você não conheça, pode utilizar este artigo.

Handler de evento "nova barra"
Handler de evento "nova barra"
  • www.mql5.com
Os autores dos indicadores e especialistas sempre estiveram interessados em escrever o código compacto em termos de tempo de execução. Você pode resolver este problema a partir de diferentes ângulos. A partir deste amplo tópico neste artigo, cobriremos o problema, que aparentemente foi solucionado: verifique por uma nova barra. Este é um meio...
 
Joscelino Celso de Oliveira:

Como eu faria:

- Usaria a estutura MqlRates;

- utilizaria o ArraySetAsSeries na variavel candle[];

- Criaria uma variável int para contar o numero de barras (conta_barras);

- Criaria variáveis do tipo static para armazenar os valores OHLC do primeiro candle;

- Apos verificar a formação do 2o candle, eu armazenaria os dados do 1o candle nas variaveis static. Dai poderia utiliza-las a qualquer momento.

- A logica ficaria mais ou menos assim:

if(conta_barras==2){variavel_static_1=candle[1].open;variavel_static_2=candle[1].high;variavel_static_3=candle[1].low;variavel_static_4=candle[1].close;}

OBSERVAÇÃO: Pensei isto em face do que escreveu. Precisa testar. De qualquer forma, acredito que ocupe um numero menor de linhas de código e que vai funcionar.

Para verificar a formação de nova barra, caso você não conheça, pode utilizar este artigo.

Olá Joscelino,

Achei legal sua solução. Agora estou com a cabeça cansada demais, preciso de uma pausa. Mas à noite faço e te falo se deu certo ou não.

Obrigado amigo e grande abraço.

 
Ruy Christian Hoffmann:


Ruy, depois de identificar o horário de abertura (time), você pode utilizar a função abaixo para localizar a barra que deseja:

int  iBarShift( 
   const string        symbol,          // Symbol 
   ENUM_TIMEFRAMES     timeframe,       // Period 
   datetime            time,            // Time 
   bool                exact=false      // Mode 
   );



//--- Exemplos:

HighOpenBar = iHigh(NULL, PERIOD_CURRENT, iBarShift(NULL, PERIOD_CURRENT, OpenTime, true));
LowOpenBar  = iLow (NULL, PERIOD_CURRENT, iBarShift(NULL, PERIOD_CURRENT, OpenTime, true));



//--- Verificar se a barra foi realmente localizada:

if(HighOpenBar > 0) ...

if(LowOpenBar > 0) ...
 
Ruy Christian Hoffmann:

Olá Joscelino,

Achei legal sua solução. Agora estou com a cabeça cansada demais, preciso de uma pausa. Mas à noite faço e te falo se deu certo ou não.

Obrigado amigo e grande abraço.

Bom dia Joscelino,

Rapaz... nada como um descanso + dica do amigo para aparecer uma solução. 

Inspirado na sua ideia eu fiz o código abaixo, pode não ter ficado tão bonito quanto a função do Vinícius, mas está funcionando, veja:

   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   int copied=CopyRates(_Symbol,_Period,0,81,rates);

   int HoraLimite=480;
   MqlDateTime RelogioBarra;
   TimeToStruct(rates[0].time,RelogioBarra);
   int Minutos=RelogioBarra.hour-9;
   if(Minutos!=0)
      Minutos = Minutos*60;
   
   Minutos=Minutos+RelogioBarra.min;
   int BarrasQtd=Minutos/Period();
   
   B1High=rates[BarrasQtd].high;
   B1Low=rates[BarrasQtd].low;
   B1Close=rates[BarrasQtd].close;

... e antes de ler o acima coloquei condicional que precisa ser entre 9-17h no M6.

E Vinícius, quando eu vi sua mensagem já tinha feito o código acima, mas o seu parece que ficou mais bem feito que o meu, profissional! Vou testar e usá-lo.

Obrigado Joscelino,

Obrigado Vinícius.

Porque a Hospedagem Virtual no MetaTrader 4 e no MetaTrader 5 são Melhores que os VPS Usuais
Porque a Hospedagem Virtual no MetaTrader 4 e no MetaTrader 5 são Melhores que os VPS Usuais
  • www.mql5.com
Alugar um servidor virtual diretamente dos terminais MetaTrader 4 e MetaTrader 5 é a melhor maneira de garantir um trabalho ininterrupto de seus robôs de negociação e das assinaturas de Sinais. Essencialmente, ele é análogo a um VPS, no entanto, ele é melhor e mais adequado para atender às necessidades e desafios que um trader se depara. O...
 
Ruy Christian Hoffmann:

Bom dia Joscelino,

Rapaz... nada como um descanso + dica do amigo para aparecer uma solução. 

Inspirado na sua ideia eu fiz o código abaixo, pode não ter ficado tão bonito quanto a função do Vinícius, mas está funcionando, veja:

... e antes de ler o acima coloquei condicional que precisa ser entre 9-17h no M6.

E Vinícius, quando eu vi sua mensagem já tinha feito o código acima, mas o seu parece que ficou mais bem feito que o meu, profissional! Vou testar e usá-lo.

Obrigado Joscelino,

Obrigado Vinícius.

#Tmj @Ruy Christian Hoffmann!

$uce$$o!

 
Ruy Christian Hoffmann:


Feliz em colaborar.

Abraço.

 
MqlRates GetMqlRatesDataByIndex(string symbol_, ENUM_TIMEFRAMES period_,  datetime dataDoDia_,  int indexBar_ = 0)
{

   int _index = 1 + indexBar_;
   int _qtdBarrasDoDia = iBarShift(
                            symbol_,
                            period_, 
                            (datetime)(StringSubstr((string)dataDoDia_, 0, 10))
                           );

   MqlRates _rates[];
   int qtd = CopyRates(symbol_, period_, _qtdBarrasDoDia - _index, 1, _rates);
   return _rates[0];
   
}


//Exemplo caso queria pergar a primeira barra do dia:

 MqlRates  mqlRate =   GetMqlRatesDataByIndex(_Symbol, _PeriodTimeCurrent(), 0);

//Exemplo caso queria pergar a segunda barra do dia:

 MqlRates  mqlRate =   GetMqlRatesDataByIndex(_Symbol, _Period,  TimeCurrent(), 1);


 

Bom Dia amigos!

Estou tbm tentando tbm pegar o primeiro candle do dia como nosso amigo Ruy, só que se coloco na gráfico atual ele funciona, mas sempre que coloco no testador em um período por ex: 11/01/2021 à 18/01/2021, ele pega o último candle do dia 08/01/2021, alguém será que pode me ajudar?

Fiz uma alteração para ter controle no tamanho do candles, pois ele precisa ter um xxx pontos pra retornar verdadeiro, enquanto ele não tiver esses pts  fica no loop para aumentando o tempo até encontrar, isso seria para formar um canal. para mini indice.

Esse é o código que estou usando com algumas 

double  CalcCandle()  //Pega sempre o primeiro candle do dia
  {

   int xWhil=0;

   ENUM_TIMEFRAMES TempoGrafico[8];

   TempoGrafico[0]=PERIOD_M5;
   TempoGrafico[1]=PERIOD_M6;
   TempoGrafico[2]=PERIOD_M10;
   TempoGrafico[3]=PERIOD_M15;
   TempoGrafico[4]=PERIOD_M20;
   TempoGrafico[5]=PERIOD_M30;
   TempoGrafico[6]=PERIOD_H1;
   TempoGrafico[7]=PERIOD_H2;

   double MaximaC=0;
   double MinimaC=0;
   double TamanhoC=0;

   while(xWhil<7)
     {
                 
MqlRates rates[];
datetime HoraINI=StringToTime(TimeToString(TimeTradeServer(), TIME_DATE));  // Pego a data que esta operando

Print("-------------------------------");  
Print("Data pega ", HoraINI);

int QtdBarras = CopyRates(_Symbol,TempoGrafico[xWhil],HoraINI,INT_MAX,rates); // Resultado no testador Data pega 2021.01.11 00:00:00
ArraySetAsSeries(rates,true);

Print("Quantidade de barras ", QtdBarras); //  // Resultado no testador  Quantidade de barras 2948
Print("-------------------------------");
  
   MaximaC=rates[0].high;
   MinimaC=rates[0].low;
   TamanhoC=MaximaC-MinimaC;
   
    
      if(TamanhoC>TamanhoMinCan)
        {
   Print("-------------------------------");    
   Print("Maxima= ", rates[0].high);  // Resultado no testador   Maxima= 125420.0
   Print("minima= ", rates[0].low);   // Resultado no testador   minima= 125155.0
   Print("Maxima= ", rates[0].time);  // Resultado no testador Maxima= 2021.01.08 18:20:00
   Print("-------------------------------");  
         return(true); 
        }

      MaximaC=0;
      MinimaC=0;
      TamanhoC=0;
      xWhil++;
     }
   return(false);
}//Fecha a Função

Mas de alguma forma ele não funciona no testador, enquanto em tempo real sim, mas queria saber a eficácia do canal pego.

Alguém tem ideia de o pq isso acontece?


Agradecido!

 
Vinicius de Oliveira:

Ruy, depois de identificar o horário de abertura (time), você pode utilizar a função abaixo para localizar a barra que deseja:

Vinicius, como faço para identificar o horário de abertura para poder alocar na variável OpenTime. Já quebrei cabeça e não consegui.

Obrigado pela contribuição.

 
Bruno Peres:

Vinicius, como faço para identificar o horário de abertura para poder alocar na variável OpenTime. Já quebrei cabeça e não consegui.

Obrigado pela contribuição.

Boa noite @Bruno Peres.


Acredito que o horário de abertura poderia ser informado nos parâmetros de entrada mesmo. Então você poderia fazer assim:

//=== Enumerations
enum ENUM_TIME
  {
   H00M00 =     0,      // 00:00
   H01M00 =  3600,      // 01:00
   H02M00 =  7200,      // 02:00
   H03M00 = 10800,      // 03:00
   H04M00 = 14400,      // 04:00
   H05M00 = 18000,      // 05:00
   H06M00 = 21600,      // 06:00
   H07M00 = 25200,      // 07:00
   H08M00 = 28800,      // 08:00
   H09M00 = 32400,      // 09:00
   H10M00 = 36000,      // 10:00
   H11M00 = 39600,      // 11:00
   H12M00 = 43200,      // 12:00
   H13M00 = 46800,      // 13:00
   H14M00 = 50400,      // 14:00
   H15M00 = 54000,      // 15:00
   H16M00 = 57600,      // 16:00
   H17M00 = 61200,      // 17:00
   H18M00 = 64800,      // 18:00
   H19M00 = 68400,      // 19:00
   H20M00 = 72000,      // 20:00
   H21M00 = 75600,      // 21:00
   H22M00 = 79200,      // 22:00
   H23M00 = 82800       // 23:00
  };

//=== Input parameters
input ENUM_TIME iOpenTime = H09M00;   // Horário de Abertura

. . .

//=== Obter Horário de Abertura
datetime OpenTime = iTime(NULL, PERIOD_D1, 0) + iOpenTime;
Razão: