类似于iBarShift - 页 3

 
Vasiliy Pushkaryov:

以下是剧本。

它只是挂起。强行将其从图表中删除,就能得到结果。

所以我试了一下,这就是为什么我向你推荐它。但既然你用了它,而且它适合你,我不会改变主意。

我很抱歉,瓦西里。我误解了你的意思。我只是在开车时迅速读了你的帖子。我以为是关于最后一个参数的问题,我的参数是32000000000,原来你是指t参数。是的,确实如此--这是唯一的一种情况,其结果与原来的MQL4 iBarShift()不同。然而,如果试图用这个函数来获取从当前时间点开始的条数(或条数指数),即TimeCurrent(),则非常奇怪,因为很明显条数是零。一般来说,奇怪的是TimeCurrent() 中的Bars() 函数产生0,而不是1,从形式上看是开发者的错误,尽管这取决于。但不可能因为使用标准的Bars()函数而挂掉,尤其是脚本检查了Print(),即一切正常。
请理解,Vasily,我不想贬低iBarShift模拟的其他实现,只是我个人正是使用这种结构(Bars(NULL,0,t,32000000000)-1;), 因为这是最快速的。而这个结构并不是用来替代iBarShift的,而只是作为一个在指定时间寻找一个柱状物的索引的功能,我不明白你说的普遍性是什么意思。而且我认为,由于时间成本较高,使用上述所有的功能是不合理的。(记得多斯雅粉的商业广告)。问题是,使用这个函数很多时候发生在大循环中,这大大增加了程序的运行时间,而我对运行时间的贪婪是可怕的。我在计算各种函数的运行时间方面做了实验(不仅是我,见以前的帖子),这个选项绝对是最快的。即使是这个 被定位为最快的变体 也是如此,但(Bars(NULL,0,t,32000000000)-1;) 结构 更加简单 当然,使用什么由大家自己决定。

无论如何,感谢你的实质性评论。

 
Nikolai Semko:

但如果试图用这个函数来接收从当前时刻开始的条数(或条数的索引),即TimeCurrent(),而此时已经很清楚条数是零,那就非常奇怪了。总的来说,奇怪的是,TimeCurrent()的Bars() 函数给出了0,而不是1。

TimeCurrent() 只是我手头的一个特殊案例。

我现在更仔细地阅读了Bars() 函数的这个注释。

"当要求在一个给定的日期范围内的酒吧数量,只考虑那些开盘时间在该范围内的酒吧。例如,如果当前的工作日是星期六,当要求获得start_time=lastTuesday和stop_time=lastFriday的周线数量时,函数返回0,因为周线时间框架的开盘时间总是在星期天,没有周线落入指定范围"。

由于TimeCurrent() 几乎所有的时间都晚于当前条形的开盘时间,所以Bars() 函数返回0。因此,如果我们将小时时间框架上的02:05所对应的时间作为start_time 参数传递,并且我们希望2点钟开始的条形有效,那么我们必须通过CopyTime() 获得条形的开盘时间(02:00:00)。否则 ,函数Bars() 将忽略此条

例如,如果时间是3:30,我理解在每小时的TF中,时间2:05指的是索引为1的条形图。 第2页上的函数都不会返回这个索引。通过这一修正,雷纳特-阿赫蒂亚莫夫的 函数返回了我预期的结果。

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

我附上一个脚本,有4个索引查找功能的选项,我把它作为一个测试。

附加的文件:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

TimeCurrent() 只是遇到的一个特殊情况。

我现在更仔细地阅读了Bars() 函数的这个注释。

"当要求在一个给定的日期范围内的酒吧数量,只考虑那些开盘时间在该范围内的酒吧。例如,如果当前的星期是星期六,当要求start_time=lastTuesday和stop_time=lastFriday的周线数量时,函数返回0,因为周线时间框架的开盘时间总是在星期天,没有周线落入指定范围"。

由于TimeCurrent() 几乎所有的时间都晚于当前条形的开盘时间,所以Bars() 函数返回0。因此,如果我们将小时时间框架上的02:05所对应的时间作为start_time 参数传递,并希望在2点钟开始的条形被验证,那么我们必须通过CopyTime() 获得条形的开盘时间(02:00:00)。否则 ,函数Bars() 将忽略此条

例如,如果现在的时间是3:30,我理解在每小时的时间框架中,2:05指的是索引为1的条形。这个索引不会被第二页的任何函数返回。通过这一修正,雷纳特-阿赫蒂亚莫夫的 函数返回了我预期的结果。

我附上一个脚本,有4个索引查找功能的选项,我把它作为一个测试。

当然,我需要通过酒吧的时间。我忘了说明。
 
我不明白为什么这个功能在SB中还不存在
 
transcendreamer:
我不明白为什么这个功能在SB中仍然不可用。

试过所有的变体,最正确的是来自Alain Verleyen。
(在一个有很多对象的复杂指标上测试)
 
Taras Slobodyanik:

试过所有的变体,最正确的是来自Alain Verleyen。
(在有大量对象的复杂指标上测试)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • 投票: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

在我看来,使用SeriesInfoInteger 函数是多余的,因为它不是免费的。

是。

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

成为了。

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

速度增益约为1.5倍。

而且这似乎是最快的选择。真,最后一个参数Exact 是假的,它可以被删除。但在我看来,这没有必要。就我个人而言,我从未遇到过需要Exact= true的任务。

但如果有人需要它,他不能没有CopyTime,最好使用@Alain Verleyen的变体

SZY: 我已经绕过了对函数PeriodSeconds 的多余调用,如果TF在上次调用后没有变化。虽然收益很弱--几个百分点,但还是有的。

还有一句话:建筑

time-=time%PerSec;
将不能与PERIOD_W1和PERIOD_MN1正常工作,因为它从1970年1月1日开始,那不是一个星期一,而是一个星期四。而每个月都有不同的秒数。
 
Nikolai Semko:

在我看来,使用SeriesInfoInteger 函数是多余的,因为它不是免费的。

是。

成为了。

速度增益约为1.5倍。

而且这似乎是最快的选择。真,最后一个Exact 参数是假的。但如果你问我,你不需要它。

还是我错了?

SZY: 我还绕过了对PeriodSeconds 函数的多余调用,如果TF在上次调用后没有变化。收益真的很轻微--几个百分点,但仍然是。

我不明白这段代码有多聪明,这就是为什么我想问你一个问题。如果图表不是全天的,这个代码会起作用吗?

 
Aleksey Vyazmikin:

代码有多深奥,我不太清楚,所以我就问了。如果图表不是全天的,这个代码会起作用吗?

我不明白这个问题的实质。换个角度说吧。

图中除了每天的第一秒外,总是没有一整天的时间。

我们谈论的是什么时间框架?一天?

又是什么阻止了你去检查?

这段代码不是我的,我只是简化了它,使它更快。

在我之前的信息中,我对PERIOD_W1和PERIOD_MN1 进行了补充。

之前所有的算法,包括@Alain Verleyen的,都有不正常的情况。

你可以创建一个完整的iBarShift MQL4的类似物,但代码将是相当繁琐的,我不认为有任何意义。

 
Nikolai Semko:

我不明白这个问题的意义。换个角度说吧。

图中除了每天的第一秒外,总是没有一整天的时间。

我们在谈论的是什么TF?一天?

又是什么阻止了你去检查?

这段代码不是我的,我只是简化了它,使它更快。

在我之前的信息中,我对PERIOD_W1和PERIOD_MN1 进行了补充。

之前所有的算法,包括@Alain Verleyen的,都有不正常的情况。

你可以创建一个完整的iBarShift MQL4的类似物,但代码将非常繁琐,我不认为有什么意义。

我没有测试过,因为人们必须确定代码在某种情况下是否有效,否则,如果他/她犯了错误,责备别人是不对的。

我说的是这样的情况:假设我们一天有14个小时(或者更少,如果每小时没有报价的话),我有一个M1图表,我需要知道前一天M15上的一个柱子的位移。也就是说,如果我在一小时内有45分钟,或在一天内有14小时,或任何其他时间/开关的下降,一切都能正确工作吗?