类似于iBarShift - 页 12

 
Nikolai Semko :

你说过,一切都应该在MQL4中工作

但这个脚本也可以在MQL5中运行

在精确=True和未来时间的情况下,你应该返回-1

我的脚本也发现了一个奇怪的错误。

这个错误被这个检查所证实。

所以我对你的算法中存在异常情况 的看法毕竟是正确的。

你终于发现了错误,这很好

我会去看看的,谢谢你。

 

大家晚上好。也许我误解了什么,但还是--不太清楚标准函数有什么问题,在Bars()的开头已经建议过了。我一直在使用它,它没有引起任何问题。唯一的问题是,在使用TimeCurrent() 时,你可能会遇到 "数组超出范围 "或负值,但这时你需要做一个检查。例子。

//найти бар на котором продали
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:

大家晚上好。也许我误解了什么,但还是--不太清楚标准函数有什么问题,在Bars()的开头已经建议过了。我一直在使用它,它没有引起任何问题。唯一的问题是,在使用TimeCurrent() 时,你可能会遇到 "数组超出范围 "或负值,但这时你需要做一个检查。例子。

从数字32000000000来看,这也是我的创作。UINT_MAX只是更短,看起来更牢固。))

关键是,事实证明,这种变体更正确。

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

而不是

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

几乎没有外部差异。但是上面的变量非常精确地重复了MQL4的标准iBarShift函数

 
Nikolai Semko:

从数字32000000000来看,这也是我的创作。UINT_MAX只是看起来更短,更稳固。))

关键是,事实证明,这种变体更正确。

而不是

几乎没有外部差异。但上面的变量非常精确地重复了MQL4的标准iBarShift功能。

那么,什么是最简单和正确的呢?

 
Vitaly Muzichenko:

那么,什么是最简单、最正确的事情呢?

到目前为止,这个变体,但现在我想补充它,以绕过Bars 功能冻结的错误,关于这个问题,我已经向服务台报告。

这个错误的本质是,如果在Bars函数中,start_timestop_time 都在一个柱状体内或在未来(零柱的右边),那么这个函数会挂起超过10秒。

也许我以后会做一个适当的更快但更麻烦的版本。

 

我已经决定走一条不同的路。
我不会重做iBarShift,但会重做故障的Bars功能

而新的iBars功能不仅会绕过打嗝的毛病,也会比原来的Bars更快。

其他人将能够使用这一功能,已经到位的算法将更快地工作。

我只是需要时间。我将在一天后才能够做到这一点。

 
Nikolai Semko:

我决定走一条不同的路线。
我不会重做iBarShift,但会重做故障的Bars功能

而新的iBars功能不仅会绕过打嗝的毛病,也会比原来的Bars更快。

其他人将能够使用这一功能,已经到位的算法将更快地工作。

我只是需要时间。在某一天之前不会做。

非常好!期待着!

 
Nikolai Semko:

从我所做的所有分析中,我们可以得出结论,这个完全模拟的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);
  }

是迄今为止最正确的,同时也是最快的,而且是最简单和最短的算法。

这很好,但有些东西让我感到困惑......

将不得不测试它 )

 

iBars功能相当麻烦,但我仍然建议使用它而不是普通的Bars,直到MQ修复了其中的挂起错误。

iBar在逻辑上应该返回0的时候却挂了。作为一项规则,它的返回时间超过10秒。在MQL4中没有这样的错误。

在大多数任务中,iBars会比普通的Bars工作得更快,因为它不仅会避免这个错误,而且由于保存前值的算法,尽可能不使用Bars 和SeriesInfoInteger函数

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

我已经对这个功能进行了广泛的测试。它似乎是Bars的完整副本。

也许可以用一种更优雅的方式来完成。如果你有愿望,我们欢迎你。如果你发现错误,我们将予以纠正。

所以...

那么iBarsShift函数的完整类似物将有以下形式。

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

显示iBars功能与内置Bars和iBarShift功能相比性能的指标,来自@Alain Verleyen
功能执行时间,以微秒为单位。


附加的文件: