Analógico para iBarShift - página 4

 
Nikolai Semko:

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

Foi:

Tornou-se:

Um ganho de velocidade de cerca de 1,5 vezes.

2% de ganho. Nota.

não funcionará correctamente com PERIOD_W1 e PERIOD_MN1, porque é contado a partir de 1 de Janeiro de 1970, e é quinta-feira, e não segunda-feira. E cada mês tem um número de segundos diferente.

Isto precisa de ser adicionado à documentação do PeriodSeconds.

 
Aleksey Vyazmikin:

Não o verifiquei - porque preciso de saber ao certo se o código funcionará ou não para uma situação específica, porque não é correcto culpar outra pessoa se você mesmo 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 de tempo?

Pessoalmente, penso que é apropriado utilizar tal característica:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }

Mas é de notar que não é um análogo completo da função MQL4iBarShift, pelo menos devido ao facto de não ter o parâmetroExacto

Caso contrário, é idêntico.

Estou a colar um simples guião MQL4 que mostra a identidade completa da função padrão com este.

Se os valores da funçãoiBarShift padrão e da minha função não forem iguais, então Imprimir. Não imprimiu nada para mim.

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime t=TimeCurrent()+1000;
   const ENUM_TIMEFRAMES tf[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
   while(!IsStopped())
     {
      for(int i=0; i<9;i++)
        {
         int i1=iBarShift(NULL,tf[i],t);
         int i2=iBarShift2(NULL,tf[i],t);
         if(i1!=i2) Print(EnumToString(tf[i]),"   ",TimeToString(t),"   ",i1,"   ",i2);
        }
      t-=10;
      Comment(TimeToString(t));
     }

  }
//+------------------------------------------------------------------+
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
 
fxsaber:

2% de taxa de vitória. Nota.

O quê, realmente?

Eu era demasiado preguiçoso para colocar GetMicrosecondCount(), por isso confiei na definição de perfis.

 
Nikolai Semko:

A sério?

Eu era demasiado preguiçoso para definir GetMicrosecondCount(), por isso confiei na definição de perfis.

O perfilamento é sobre outra coisa. 2% é o ganho máximo que se pode obter.

250 milhões de chamadas no Testador no meu atendedor dá uma economia de 1 segundo.

Definitivamente, a sua opção é a melhor! Mas nem consigo imaginar porque é que em MT5 se precisa de trabalhar com bares.

 
fxsaber:

Mas não faço ideia porque é que no MT5 preciso de trabalhar com bares.

Utilizo-a quando controlo o rato. Por exemplo, aqui.

 
Nikolai Semko:

Utilizo isto quando controlo o rato. Aqui, por exemplo.

Sim, isso é o que não compreendo.

 
fxsaber:

Sim, é isso que eu não compreendo.

E eu não entendo o mal-entendido ))

Por exemplo, tenho um canal, uma das características do qual é a hora de início (margem esquerda). E eu preciso de construir este canal em diferentes TFs. Bem, que outra alternativa tenho senão encontrar o número do bar numa nova TF?

Tenho muitas outras coisas.

Por exemplo, quando combino todas as TFs em uma só com uma escala logarítmica. Este é um tópico muito fixe. Aqui também não se pode passar sem o analógico iBarShift

 
Nikolai Semko:

Pessoalmente, penso que é razoável utilizar tal função:

Mas é de notar que não é um análogo completo da função padrão MQL4iBarShift, pelo menos porque não tem o parâmetroExacto

Caso contrário, é idêntico.

Estou a colar um simples guião MQL4 que mostra a identidade completa da função padrão com este.

Se os valores da funçãoiBarShift padrão e da minha função não forem iguais, então Imprimir. Não imprimi nada.

Não, não o fez por causa de Comentário().

Se a removermos, há um desfasamento por 1, mas não creio que seja um erro, porque na realidade a nova barra é definida em dois algoritmos com um deslocamento por metade de uma barra. A minha versão de nova detecção de barras parece-me mais lógica do que a normal.

 
Nikolai Semko:

E eu não entendo o mal-entendido ))

Não compreendo o objectivo de usar barras. CopyRates, etc.

 

Porque é que o guião é tão lento?

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:20:49.300 Scripts script BS (Si Splice,H4) loaded successfully

2018.03.30 09:21:20.209 Scripts script BS (Si Splice,H4) removed

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

input ENUM_TIMEFRAMES TF=PERIOD_D1;
input int Bar=3;
input int calcN=1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("1 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("1 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }



   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift2(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("2 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("2 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }
   return;

  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+  
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+   
int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
   if(index < 0) return(-1);
   datetime Arr[];
   if(CopyTime(symbol,tf,index,1,Arr)>0)
      return(Arr[0]);
   else return(-1);
  }
//+------------------------------------------------------------------+