Analógico para iBarShift - página 3

 
Vasiliy Pushkaryov:

Aqui está o guião.

Apenas fica pendurado. A sua remoção forçada do gráfico obtém o resultado.

Por isso, experimentei-o e foi por isso que lho recomendei. Mas como a usou e lhe convém, não vou mudar de ideias.

Sinto muito, Vassili. Compreendi-o mal. Basta ler o seu post rapidamente enquanto eu conduzia. Pensei que se tratava do último parâmetro, onde tenho32000000000, afinal referia-se ao parâmetro t. Sim, de facto - é o único caso em que o resultado é diferente do original MQL4 iBarShift(). Contudo, é muito estranho tentar usar esta função para obter o número de barras (ou índice de barras) a partir do ponto temporal actual, ou seja,TimeCurrent(), quando é claro que a barra é zero. Em geral, é estranho que a funçãoBars() noTimeCurrent() produza 0, e não 1. Formalmente é uma falha dos programadores, embora dependa. Mas algo não pode ser pendurado devido à utilização da função Bars() padrão, especialmente desde que o script verificouPrint(), ou seja, tudo está OK.
Compreenda, Vasily, não quero menosprezar outras implementações do análogo iBarShift, só que eu pessoalmente uso exactamente esta construção(Bars(NULL,0,t,32000000000)-1;), porque é a mais rápida. E esta construção é utilizada não como um substituto do iBarShift, mas simplesmente como uma função de encontrar um índice de uma barra num determinado momento, e não entendo o que se entende por universalidade. E não creio que seja razoável utilizar todas as funções acima referidas devido ao custo de tempo mais elevado. (Lembre-se dos anúncios do Dosya em pó). O problema é que a utilização desta função acontece muito frequentemente em grandes ciclos, o que aumenta significativamente o tempo de execução do programa, e eu sou terrivelmente ganancioso pelo tempo de execução. Fiz experiências no cálculo do tempo de execução de várias funções (e não só eu, ver post anterior) e esta opção é definitivamente a mais rápida. Mesmo esta variante, que é posicionada como a mais rápida, é a mesma, mas a construção(Bars(NULL,0,t,32000000000)-1;) é ainda mais simples. É claro, cabe a todos o que usar.

Em todo o caso, obrigado pela sua observação substantiva.

 
Nikolai Semko:

Mas é muito estranho tentar usar esta função para receber o número de barras (ou o índice de uma barra) a partir do momento actual, ou seja,TimeCurrent(), quando já é claro que a barra é zero. Em geral, é estranho que a funçãoBars() noTimeCurrent() dê 0, e não 1. Formalmente, é uma falha dos programadores, embora dependa.

TimeCurrent() era apenas um caso especial que eu tinha em mãos.

Agora leio esta nota para a função Bars() com mais atenção:

"Ao solicitar o número de barras num determinado intervalo de datas , só são tidas em conta as barras cujo tempo de abertura se encontre dentro desse intervalo. Por exemplo, se o dia actual da semana for sábado, ao solicitar o número de bares semanais com start_time=lastTuesday e stop_time=lastFriday, a função retorna 0 porque a hora de abertura do horário semanal cai sempre ao domingo e nenhum bar semanal se enquadra no intervalo especificado".

Uma vez que TimeCurrent() é quase sempre posterior à hora de abertura da barra actual, então a função Bars() retorna 0. Assim, se passarmos o tempo correspondente a 02:05 no horário horário como o parâmetro start_time , e quisermos que a barra que começou às 2 horas seja válida, então temos de obter a hora de abertura da barra (02:00:00) através de CopyTime() . Caso contrário, a função Bars() irá ignorar esta barra.

Ou seja, se a hora for 3:30, entendo que no TF horário, a hora 2:05 se refere à barra com índice 1. Nenhuma das funções da 2ª página devolverá este índice. Com esta correcção, a função de Renat Akhtyamov devolveu o que eu esperava.

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

Estou a anexar um guião, com 4 opções para funções de pesquisa de índice, que utilizei como teste.

Arquivos anexados:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

OTimeCurrent() é apenas um caso especial encontrado.

Agora leio esta nota para a função Bars() com mais atenção:

"Ao solicitar o número de barras num determinado intervalo de datas , só são tidas em conta as barras cujo tempo de abertura se encontre dentro desse intervalo. Por exemplo, se o dia actual da semana for sábado, ao solicitar o número de bares semanais com start_time=lastTuesday e stop_time=lastFriday, a função retorna 0 porque a hora de abertura do horário semanal cai sempre ao domingo e nenhum bar semanal se enquadra no intervalo especificado".

Uma vez que TimeCurrent() é quase sempre posterior à hora de abertura da barra actual, então a função Bars() retorna 0. Assim, se passarmos o tempo correspondente a 02:05 no horário horário como o parâmetro start_time , e quisermos que a barra que começou às 2 horas seja válida, então temos de obter a hora de abertura da barra (02:00:00) através de CopyTime() . Caso contrário, a função Bars() irá ignorar esta barra.

Isto é, se a hora é agora 3:30, entendo que no período horário, 2:05 refere-se à barra com índice 1. Este índice não será devolvido por nenhuma função da 2ª página. Com esta correcção, a função de Renat Akhtyamov devolveu o que eu esperava.

Estou a anexar um guião, com 4 opções para funções de pesquisa de índice, que utilizei como teste.

É claro que preciso de passar o tempo do bar. Esqueci-me de especificar.
 
Não compreendo porque é que esta função ainda não existe no SB
 
transcendreamer:
Não percebo porque é que esta função ainda não está disponível no SB

Testadas todas as variantes, a mais correcta é a de Alain Verleyen.
(testado num indicador complexo com muitos objectos)
 
Taras Slobodyanik:

Testadas todas as variantes, a mais correcta é a de Alain Verleyen.
(testado em indicador complexo com lotes de objectos)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • votos: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

Na minha opinião, a utilização da funçãoSeriesInfoInteger é redundante, porque não é gratuita.

Foi:

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

Tornou-se:

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame) || (Exact!=LastExact))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

O ganho de velocidade é cerca de uma vez e meia.

E parece ser a opção mais rápida. Verdadeiro, último parâmetroExacto é falso, e pode ser removido. Mas quanto a mim, não é preciso. Pessoalmente, nunca encontrei tarefas onde precisássemosExacto= verdadeiro.

Mas se alguém precisar, não pode passar sem o CopyTime e é melhor usar avariante de@Alain Verleyen.

SZY: Eu ignorei chamadas supérfluas para a funçãoPeriodSeconds, se a TF não tiver mudado desde a última chamada. O ganho é fraco, no entanto - alguns por cento, mas ainda assim.

E mais uma observação: Construção

time-=time%PerSec;
não funcionará correctamente com PERIOD_W1 e PERIOD_MN1 porque começa em 1 de Janeiro de 1970, que não é uma segunda-feira, mas sim uma quinta-feira. E cada mês tem um número de segundos diferente.
 
Nikolai Semko:

Na minha opinião, a utilização da funçãoSeriesInfoInteger é redundante, porque não é gratuita.

Foi:

Tornou-se:

O ganho de velocidade é cerca de uma vez e meia.

E parece ser a opção mais rápida. É verdade, o último parâmetroExacto é falso. Mas se me perguntarem, não precisam dele.

Ou estarei eu errado?

SZY: Também ignorei chamadas supérfluas para a funçãoPeriodSeconds, se a TF não tiver mudado desde a última chamada. O ganho é realmente ligeiro - alguns por cento, mas mesmo assim.

Não compreendo como este código é inteligente, é por isso que lhe quero fazer uma pergunta. Será que o código funcionará se o gráfico não for de dia inteiro?

 
Aleksey Vyazmikin:

Como o código é abstruso, não é claro para mim, por isso vou perguntar. Será que o código funcionará se o gráfico não for de dia inteiro?

Não compreendo a essência da questão. Colocá-lo de uma forma diferente.

O gráfico não é sempre um dia inteiro, excepto no primeiro segundo do dia.

De que prazo estamos a falar? Um dia?

E o que o impede de verificar?

O código não é meu, apenas o simplifiquei e tornei-o mais rápido.

Na minha mensagem anterior fiz uma adição sobrePERIOD_W1 e PERIOD_MN1.

Todos os algoritmos anteriores, incluindo @Alain Verleyen's, têm situações anormais.

Pode-se criar um análogo completo de iBarShift MQL4, mas o código será bastante pesado, e não vejo qualquer sentido nele.

 
Nikolai Semko:

Não compreendo o objectivo da pergunta. Colocá-lo de uma forma diferente.

O gráfico não é sempre um dia inteiro, excepto no primeiro segundo do dia.

De que TF estamos a falar? Um dia?

E o que o impede de verificar?

O código não é meu, apenas o simplifiquei e tornei-o mais rápido.

Na minha mensagem anterior fiz uma adição sobrePERIOD_W1 e PERIOD_MN1.

Todos os algoritmos anteriores, incluindo @Alain Verleyen's, têm situações anormais.

Pode-se criar um análogo completo de iBarShift MQL4, mas o código será muito pesado, e não vejo qual o objectivo nisso.

Não o testei porque é preciso saber ao certo se o código funcionará para uma determinada situação, caso contrário não é correcto culpar outra pessoa se esta cometeu um erro.

Estou a falar de situações como esta: suponha que temos 14 horas num dia (ou menos, se não houvesse citações a cada hora), tenho um gráfico M1 e preciso de saber o turno de um bar em M15 para o dia anterior. Isto é, tudo funcionará correctamente se eu tiver 45 minutos numa hora ou 14 horas num dia, ou qualquer outro tempo/desvio?