Аналог iBarShift - страница 15

 
Alexey Kozitsyn:
Кстати, по поводу функции Bars(). Возможно - это причина клинча.
Это легко проверить. Поменять все Bars  на мою  iBars. Если исчезнет клинч , тогда проблема в этой функции. Я тоже не мог понять причину заморозки некоторых своих индикаторов. Оказался именно этот баг.  Теперь все летает.
 
fxsaber:

Котиры могут идти по всем символам, кроме интересуемого.

Ладно, посмотрел новый исходник. Увидел, что правки, которые обсуждали, не сделаны. Выхожу.

Использовать SYMBOL_TIME имеет смысл лишь в том случае, когда запрашиваемого символа нет в окне "Обзор рынка". Тогда TimeCurrent не будет справляться со своей задачей. Но мне представляется маловероятным такой вариант использования Bars. Зато цена получения текущего времени через SYMBOL_TIME намного выше, потому как SymbolInfoInteger(symbol_name,SYMBOL_TIME) работает почти на порядок дольше. Можно, конечно, выяснять, есть ли такой символ в обзоре рынка и в зависимости от результата использовать TimeCurrent или SYMBOL_TIME, но это тоже не бесплатно, тем более все время нужно мониторить, не добавился или удалился ли новый символ из обзора рынка. Поэтому проще сделать оговорку, что для корректной работы iBars целесообразно чтобы запрашиваемый символ был в обзоре рынка.

Про SERIES_LASTBAR_DATE я думаю, что Вы не правы. SymbolInfoInteger(symbol_name,SYMBOL_TIME) - это меньшее зло.

Никакой подкачки истории функция SeriesInfoInteger не вызывает. Если что ее и вызывает, то это запрос Bars, что логично. И источник тормозов видно из этого короткого скрипта, если его запустить

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

Вообще очень странный баг. Я проверил влияние на него истории закачки, когда обнаружил, что вдруг сегодня на символе EURUSD он практически не появлялся.

Принудительно загрузил всю историю. И баг снова появился.

Пожалуй, история закачки не оказывает влияния на этот баг. 

Не понимаю, почему этот баг плавающий. 

Использовал для проверки этот скрипт:

Файлы:
TestiBars.mq5  11 kb
 
Nikolai Semko:

Не понимаю, почему этот баг плавающий. 

А СД в курсе всей этой темы?

 
Вообще, считаю, что загрузка/подгрузка данных - слабое место терминала.
 
Alexey Kozitsyn:

А СД в курсе всей этой темы?

Да, уже написал туда 30.03.2018 - пока тишина.

Alexey Kozitsyn:
Вообще, считаю, что загрузка/подгрузка данных - слабое место терминала.

Согласен, но это еще и одна из самых сложных задач.

 
Nikolai Semko:

функция iBars хоть и получилась весьма громоздкой, но всё равно я рекомендую её использовать вместо штатного Bars, пока MQ не исправят в нем баг с зависанием. 

Зависает iBar, когда по логике он должен возвращать 0. Возвращает он его как правило более 10 секунд. В MQL4 этого бага нет.

В большинстве задач iBars будет работать быстрее чем штатный Bars, потому как она не только обходит баг, но и старается не  использовать по возможности функции Bars и SeriesInfoInteger благодаря алгоритму сохранения предыдущих значений.

Тестировал эту функцию и вдоль и поперек. Вроде бы полностью повторяет Bars.

Возможно можно сделать более изящно. У кого есть желание - милости просим. Найдете ошибки - будем исправлять.

Итак...

Тогда полный аналог функции iBarsShift будет иметь вид:

А вариант без последнего параметра exact, что используется в подавляющем большинстве случаев будет иметь такой вид:

Использую Ваш код iBarsShift+iBars (и другие iBarsShift) и получаю 0 от iBarsShift , а при TF чарта H1 и расчете на H1 ошибку

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

что соответствует этой строке кода

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

Вот код индикатора целиком 

#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);
  }

Почему Print(Day_Shift) всегда возвращает ноль, в то время как время и дата опредеяется верно?

Такое ощущение, что это эффект выходного дня, так как намедни все работало корректно (правда с другой функцией, но и она не работает сегодня).

 
Aleksey Vyazmikin:

Использую Ваш код iBarsShift+iBars (и другие iBarsShift) и получаю 0 от iBarsShift , а при TF чарта H1 и расчете на H1 ошибку

что соответствует этой строке кода

Вот код индикатора целиком 

Почему Print(Day_Shift) всегда возвращает ноль, в то время как время и дата опредеяется верно?

Такое ощущение, что это эффект выходного дня, так как намедни все работало корректно (правда с другой функцией, но и она не работает сегодня).

Я прошу прощения, что оставил код в неправильном виде. 

Я заметил еще тогда неточную работу и почти исправил ее, но осталась маленькая легкоустранимая проблема.
Просто я забросил код по причине того, что сейчас учусь и у меня началась пора экзаменов и просто нет времени. Последний экзамен 24 апреля.
После него все исправлю и опубликую в CB. 

Я уже начал публикацию, но приостановил её.


 
Nikolai Semko:

Я прошу прощения, что оставил код в неправильном виде. 

Я заметил еще тогда неточную работу и почти исправил ее, но осталась маленькая легкоустранимая проблема.
Просто я забросил код по причине того, что сейчас учусь и у меня началась пора экзаменов и просто нет времени. Последний экзамен 24 апреля.
После него все исправлю и опубликую в CB. 

Я уже начал публикацию, но приостановил её.


Буду ждать исправлений в окончательной форме, спасибо, что ответили.

Удачи с экзаменами!

 
Aleksey Vyazmikin:

Буду ждать исправлений в окончательной форме, спасибо, что ответили.

Удачи с экзаменами!

Спасибо))
Причина обращения: