Analógico para iBarShift - página 12

 
Nikolai Semko :

Disse que tudo deveria funcionar na MQL4.

Mas este guião também pode ser executado em MQL5

Com exactidão=Verdade e tempo futuro deverá regressar -1

O meu guião também encontrou um estranho erro:

Este erro é confirmado por esta verificação:

Por isso, afinal tinha razão sobre a existência de situações anormais no vosso algoritmo.

É bom que tenha finalmente encontrado o erro

Irei verificar, obrigado.

 

Boa noite a todos. Talvez esteja a interpretar mal alguma coisa, mas mesmo assim - não é bem claro o que está errado com a função padrão, que já foi sugerida no início do Bars(). Tenho estado sempre a usá-lo e não tem causado quaisquer problemas. A única coisa é que pode encontrar "array fora do intervalo" ou valor negativo ao utilizar o TimeCurrent(), mas depois precisa de fazer uma verificação para o verificar. Exemplos:

//найти бар на котором продали
Bar_sell_H4=Bars(Symbol(),PERIOD_H4,P_opentime,32000000000)-1;
if(Bar_sell_H4<=0)
   {
      Bar_time_sell_H4=Time_H4[0];
   }
else
   {
      Bar_time_sell_H4=Time_H4[Bar_sell_H4];
   }
Bars_forsearch_highfr_H1=Bars(Symbol(),PERIOD_H1,TimeCurrent(),Time_M15[B_DownTrend_M15_int]);
if(Bars_forsearch_highfr_H1<=0)
   {
      high_H1_int=0;
   }
else
   {
      high_H1_int=ArrayMaximum(High_H1,0,Bars_forsearch_highfr_H1);
   }
 
Almat Kaldybay:

Boa noite a todos. Talvez esteja a interpretar mal algo, mas mesmo assim - não é bem claro o que está errado com a função padrão, que já foi sugerida no início do Bars(). Tenho estado sempre a usá-lo e não tem causado quaisquer problemas. A única coisa é que pode encontrar "array fora do intervalo" ou valor negativo ao utilizar o TimeCurrent(), mas depois precisa de fazer uma verificação para o verificar. Exemplos:

A julgar pelo número 32000000000, esta é também a minha criação. UINT_MAX é simplesmente mais curto e com um aspecto mais sólido. ))

A questão é que esta variante é mais correcta, como se veio a verificar:

Bars(Symb,TimeFrame,time+1,UINT_MAX);

em vez de

Bars(Symb,TimeFrame,time,UINT_MAX)-1;

não há quase nenhuma diferença externa. Mas a variante superior repete com muita precisão a função iBarShift padrão da MQL4

 
Nikolai Semko:

A julgar pelo número 32000000000, esta é também a minha criação. UINT_MAX parece simplesmente mais curto e mais sólido. ))

A questão é que esta variante é mais correcta, como se veio a verificar:

em vez de

não há quase nenhuma diferença externa. Mas a variante superior repete com muita precisão a função iBarShift padrão da MQL4.

Então qual é a mais fácil e a mais correcta?

 
Vitaly Muzichenko:

Então qual é a coisa mais fácil e a mais correcta a fazer?

Até agora esta variante, mas agora quero complementá-la para contornar o bug do congelamento da função de Barras, sobre o qual já comuniquei ao Service Desk.

A essência deste bug é que se na função Bars tantoo tempo_de_início como otempo_de_paragem estão dentro de uma barra ou estão no futuro (à direita da barra zero), então esta função fica suspensa por mais de 10 segundos.

Talvez eu faça uma versão adequada mais rápida mas mais pesada mais tarde.

 

Decidi seguir um caminho diferente.
Não vou refazer o iBarShift, mas vou refazer a funcionalidade das Barras com falhas.

E a nova funcionalidade iBars não só contornará o bug dos soluços, como também será mais rápida do que as Barras originais.

Outros poderão utilizar esta funcionalidade e os algoritmos já existentes funcionarão mais rapidamente.

Só preciso de tempo. Só o poderei fazer um dia mais tarde.

 
Nikolai Semko:

Decidi ir por um caminho diferente.
Não vou refazer o iBarShift, mas vou refazer a funcionalidade das Barras com falhas.

E a nova funcionalidade iBars não só contornará o bug dos soluços, como também será mais rápida do que as Barras originais.

Outros poderão utilizar esta funcionalidade e os algoritmos já existentes funcionarão mais rapidamente.

Só preciso de tempo. Só o poderá fazer daqui a um dia, na melhor das hipóteses.

Muito bem! Ansioso por isso!

 
Nikolai Semko:

De toda a análise que fiz, podemos concluir que este análogo completo do iBarShift:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   int Res=Bars(Symb,TimeFrame,time+1,UINT_MAX);
   if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==Bars(Symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1);
   return(Res);
  }

é de longe o mais correcto, e ao mesmo tempo o mais rápido e com o algoritmo mais simples e mais curto.

É agradável, mas algo me confunde...

terá de o testar )

 

A função iBars é bastante pesada, mas continuo a recomendar a sua utilização em vez das Barras normais, até que o MQ corrija o bug de pendurar nela.

O iBar fica pendurado quando logicamente deve retornar 0. Como regra, devolve-o por mais de 10 segundos. Não existe tal insecto na MQL4.

Na maioria das tarefas, iBars funcionará mais rapidamente do que as Barras normais, uma vez que não só evitará o bug, como tentará não utilizar as funções Bars e SeriesInfoInteger sempre que possível, devido ao algoritmo de guardar valores anteriores.

int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_time) // stop_time > start_time
  {
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static datetime LastTime0=0;
   static int PerSec=0;
   static int PreBars=0;
   static datetime LastBAR=0;
   static datetime LastTimeCur=0;
   datetime TimeCur;
   if(stop_time<start_time) {TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; }
   TimeCur=TimeCurrent();
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec =2419200; else PerSec=::PeriodSeconds(timeframe);
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>=PerSec && TimeCur!=LastTimeCur))
      LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE);

   LastTimeCur=TimeCur;
   if(PerSec==0) return(0);
   if(start_time>LastBAR)
     {LastTimeFrame=timeframe; LastSymb=symbol_name; return(0);}

   datetime t,t0=0;
   bool check=true;
   if(timeframe<PERIOD_W1) t=start_time-(start_time-1)%PerSec;
   else if(timeframe==PERIOD_W1) t=start_time-(start_time-259201)%PerSec;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      t=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) t0=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) t0=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         t0=dt0.year*12+dt0.mon;
        }
      if(t0==t) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || t!=LastTime || t0!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=t; LastTime0=t0;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }

Tenho testado esta função em todo o lado. Parece ser uma cópia integral de Bars.

Talvez possa ser feito de uma forma mais elegante. Se tiveres um desejo, és bem-vindo. Se encontrar erros, nós iremos corrigi-los.

Por isso...

Depois, a função analógica completa do iBarsShift terá a seguinte forma:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   int Res=iBars(Symb,TimeFrame,time+1,UINT_MAX);
   if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==iBars(Symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1);
   return(Res);
  }

E variante sem último parâmetro, que é utilizada na grande maioria dos casos terá esta forma:

int iBarShift1(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   return(iBars(Symb,TimeFrame,time+1,UINT_MAX));
  }
// ИЛИ БОЛЕЕ СОКРАЩЕННЫЙ БЕЗ ФУНКЦИИ:

iBars(Symb,TimeFrame,time+1,UINT_MAX);
 

Indicador que mostra o desempenho da função iBars em comparação com as barras integradas e a função iBarShift de @Alain Verleyen
Tempo de execução da função em microssegundos.


Arquivos anexados:
Razão: