Analógico para iBarShift - página 15

 
Alexey Kozitsyn:
A propósito, sobre a função Bars(). Pode ser a causa do clincher.
Isto é fácil de verificar. Alterar todas as barras para as minhas barras iBars. Se a cunha desaparece, então o problema está nessa função. Também eu não consegui perceber a razão do congelamento de alguns dos meus indicadores. Acabou por ser este insecto em particular, agora está tudo a voar.
 
fxsaber:

Os Cotypes podem ir para todos os caracteres excepto o de interesse.

OK, olhei para o novo código fonte. Viu que as edições que foram discutidas não tinham sido feitas. Saída.

Só faz sentido utilizar SYMBOL_TIME quando o símbolo solicitado não se encontra na janela do Market Watch. Então a TimeCurrent não fará o seu trabalho. Mas esta variante de usar Barras parece-me improvável. Mas o preço de obter o tempo actual através de SYMBOL_TIME é muito mais elevado porque SymbolInfoInteger(symbol_name,SYMBOL_TIME) leva quase uma ordem de magnitude mais longa. É claro que pode verificar se o símbolo está no relatório de mercado e, dependendo do resultado, utilizarTimeCurrent ou SYMBOL_TIME, mas não é grátis, além disso tem sempre de monitorizar se um novo símbolo é adicionado ou eliminado do relatório de mercado. Por conseguinte, é mais fácil fazer uma cláusula que, para um trabalho correcto do iBars, é razoável ter o símbolo solicitado no relatório de mercado.

Sobre SERIES_LASTBAR_DATE Penso que estás errado.SymbolInfoInteger(symbol_name,SYMBOL_TIME) é o mal menor.

A função SeriesInfoInteger não causa nenhuma paginação de histórico. Se houver algo que o cause, é um pedido de Barras, o que é lógico. E a fonte dos travões pode ser vista neste pequeno guião, se o executar

void OnStart()
  {
   Print("1");
   Print(Bars(_Symbol,PERIOD_W1,D'2020.01.01 00:00',UINT_MAX));
   Print("2");
  }
 

Geralmente um insecto muito estranho. Verifiquei o efeito do histórico de descarregamento quando descobri que hoje, de repente, no símbolo EURUSD quase não apareceu.

Forçou-me a descarregar toda a história. E o insecto apareceu novamente.

Acho que o histórico de descarregamento não tem qualquer efeito sobre este bug.

Não percebo porque é que este insecto anda por aí a flutuar.

Utilizou este guião para o testar:

Arquivos anexados:
TestiBars.mq5  11 kb
 
Nikolai Semko:

Não percebo porque é que este insecto anda por aí a flutuar.

O SD está consciente de todo este tópico?

 
Em geral, penso que o carregamento/upload de dados é o ponto fraco do terminal.
 
Alexey Kozitsyn:

O SD está consciente de todo este tópico?

Sim, já lá escreveu em 30.03.2018 - até agora silêncio.

Alexey Kozitsyn:
Em geral, penso que o carregamento/upload de dados é o ponto fraco do terminal.

Concordo, mas é também uma das tarefas mais difíceis.

 
Nikolai Semko:

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.

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:

E a variante sem o último parâmetro, que é utilizada na grande maioria dos casos, terá este aspecto:

Utilizo o seu código iBarsShift+iBars (e outros iBarsShift) e recebo 0 do iBarsShift, e um erro quando o gráfico TF H1 e o cálculo para H1

2018.04.21 14:38:01.059 SVA_LinearRegression_test (Si Splice,H1)        zero divide in 'SVA_LinearRegression_test.mq5' (176,44)

que corresponde a esta linha de código

   if(timeframe<PERIOD_W1) TimeCur-=TimeCur% PerSec;

Aqui está o código de indicador como um todo

#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

//--- plot Label1
#property indicator_label1  "LR_line"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGold
#property indicator_style1  STYLE_DOT
#property indicator_width1  1
//--- plot Label2
#property indicator_label2  "Sup_line"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrAquamarine
#property indicator_style2  STYLE_DOT
#property indicator_width2  1
//--- plot Label3
#property indicator_label3  "Res_line"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrOrangeRed
#property indicator_style3  STYLE_DOT
#property indicator_width3  1


//--- input parameters
input ENUM_TIMEFRAMES TF=PERIOD_D1;
input int Bar=3;
input bool UseClose = true;


//--- indicator buffers
double LR_line_Ind[];
double Sup_line_Ind[];
double Res_line_Ind[];

//---
int limit,start;

//Список переменных:
static datetime TimeN=0;
int  barsToCount=0;

int InpChannelPeriod=1000;
double OpenI[];
double HighI[];
double LowI[];
double CloseI[];
double arr[];

double Calc_LR_line=0.0;
double Calc_Sup_line=0.0;
double Calc_Res_line=0.0;


//////////////////////////////////////////////////////////////////////

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,LR_line_Ind,INDICATOR_DATA);
   SetIndexBuffer(1,Sup_line_Ind,INDICATOR_DATA);
   SetIndexBuffer(2,Res_line_Ind,INDICATOR_DATA);   
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpChannelPeriod);
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpChannelPeriod);
   PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,InpChannelPeriod);   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{


}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   ArraySetAsSeries(LR_line_Ind,true); 
   ArraySetAsSeries(Sup_line_Ind,true); 
   ArraySetAsSeries(Res_line_Ind,true); 
   ArraySetAsSeries(time,true); 

//--- check for rates
   if(rates_total<InpChannelPeriod) return(0);
//--- preliminary calculations
   if(prev_calculated==0) limit=InpChannelPeriod;
   else limit=prev_calculated;
//--- the main loop of calculations
   for(int C=limit;C<rates_total && !IsStopped();C++)
     {
       LRegrf(C);
       LR_line_Ind[C]=Calc_LR_line;
       Sup_line_Ind[C]=Calc_Sup_line;
       Res_line_Ind[C]=Calc_Res_line;    
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
  
//+------------------------------------------------------------------+
double LRegrf(int index)
{
int Day_Shift=iBarShift(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);

Print(iTime(_Symbol,PERIOD_CURRENT,index));
Print(Day_Shift);

return (0);
}
//-------------------------------------------------------------------
//==MQL4toMQL5
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
   if(index < 0) return(-1);
//   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   //ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT;
   datetime Arr[];
   if(CopyTime(symbol,tf,index,1,Arr)>0)
      return(Arr[0]);
   else return(-1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_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(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec=2419200; else PerSec=::PeriodSeconds(timeframe);
   if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec;
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>0 && 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 tS,tF=0;
   bool check=true;
   if(timeframe<PERIOD_W1) tS=start_time-(start_time-1)%PerSec-1;
   else if(timeframe==PERIOD_W1) tS=start_time-(start_time-259201)%PerSec-1;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      tS=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         tF=dt0.year*12+dt0.mon;
        }
      if(tS==tF) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || tS!=LastTime || tF!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=tS; LastTime0=(datetime)tF;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }

Porque é que oPrint(Day_Shift) devolve sempre zero, enquanto a data e a hora estão correctas?

Parece ser um efeito de fim-de-semana, uma vez que tudo funcionava correctamente no outro dia (embora com uma função diferente, mas hoje também não funciona).

 
Aleksey Vyazmikin:

Utilizo o seu código iBarsShift+iBars (e outros iBarsShift) e recebo 0 do iBarsShift , e quando o gráfico TF H1 e calculando em H1 um erro

que corresponde a esta linha de código

Aqui está o código de indicador como um todo

Porque é que oPrint(Day_Shift) devolve sempre zero, enquanto a data e a hora estão correctas?

Parece ser um efeito de fim-de-semana, uma vez que tudo estava a funcionar correctamente no outro dia (embora com uma função diferente, mas não está a funcionar hoje também).

Peço desculpa por ter deixado o código na forma errada.

Notei a inexactidão na altura e quase a corrigi, mas ainda havia um pequeno problema, facilmente resolúvel.
Acabei de abandonar o código devido ao facto de estar a estudar agora e de os exames terem começado e de não ter tempo. O último exame realiza-se no dia 24 de Abril.
Depois disso, vou corrigir tudo e afixá-lo no CB.

Já comecei a publicá-lo, mas já o pus em espera.


 
Nikolai Semko:

Peço desculpa por ter deixado o código na forma errada.

Notei o trabalho impreciso na altura e quase o consertei, mas ainda havia um pequeno problema facilmente resolúvel.
Acabei de abandonar o código porque estou a estudar agora e o tempo de exame já começou e não tenho tempo para isso. O último exame realiza-se no dia 24 de Abril.
Depois disso, vou corrigir tudo e afixá-lo no CB.

Já comecei a afixar, mas coloquei-o em espera.


Vou esperar pelas correcções na forma final, obrigado por responder.

Boa sorte com os exames!

 
Aleksey Vyazmikin:

Vou esperar pelas correcções no formulário final, obrigado por responder.

Boa sorte com os vossos exames!

Obrigado))