程序库: 用于 MT5 的快速 iBarShift 和 Bars - 页 2

 
Alexey Navoykov:

然而,当涉及到大型计算时,iBarShift 就不合适了,因为我们使用的是数组。 事实上,iBarShift 和其他类似函数都是为罕见调用而设计的,循环使用它们是不合理的。我们只需在 CopyTime 中获取数组,然后快速找到所有内容。 这就是为什么测试示例在实际应用中用处不大的原因,当然,除非编码者是个傻瓜),而且我认为不值得为了傻瓜而费心)。

我认为将函数封装到一个类中更合乎逻辑。 这样就不必在每次调用时都检查符号/周期了。 每个时间序列都会有一个不同的对象。

我不是在争论。只是这些函数是在没有内置iBarShift 和 Bars 功能不稳定的情况下创建的。

就我个人而言,我需要这些函数来用鼠标控制程序和图表。我还使用对数刻度创建合成 TF,这些函数在这方面非常有用。它们对于解决模式识别问题非常必要,并能大大加快计算速度。这种合成 TF 包含一个符号的全部历史,仅有 3000 条柱状图。

 

我对 Bars 和 iBarShift 功能感到失望。MQ 无法让它们达到要求。它们治标不治本

我意识到,这些都是最基本的功能,最好像一个可怕的梦一样忘掉它们。

让它们继续为学生和保守派服务吧。

我认为,通过在 time[] 数组中的常规搜索来使用按时间搜索条形码是合理的。

例如,可以借助这样一个函数:

int wBarShift(datetime t,datetime &arr[],ENUM_TIMEFRAMES tf)
  {
   int size=ArraySize(arr);
   int PerSec=PeriodSeconds(tf);
   int cur,start=0;
   int fin=size-1;
   if(t<arr[0] || t>=arr[fin]) return(0);
   if(t>=arr[fin] && t<(arr[fin]+PerSec)) return(fin);
   while(true)
     {
      cur=(start+fin)/2;
      if(t<arr[cur]) {if(t>=arr[cur-1]) return(size-cur);    fin=cur;}
      else           {if(t< arr[cur+1]) return(size-cur-1);start=cur;}
      if((arr[fin]-arr[start])==((fin-start)*PerSec) && tf!=PERIOD_MN1)
         return(size-1-start-int(int(t-arr[start])/PerSec));
     }
  }

是的,你需要一个数组。但就我个人而言,我手头上总是有这个数组,而且每过一个刻度就会更新一次。所以我根本不需要数组。

而且这个函数比原来的 iBarShift 快十倍。

用半除方法在 100 000 个数组中按时间搜索条形码的示例:

2018.06.22 03:29:35.533 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 26   наносекунд, контрольная сумма = 5407361
2018.06.22 03:29:35.536 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3368 наносекунд, контрольная сумма = 5407361
2018.06.22 03:29:36.283 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 26   наносекунд, контрольная сумма = 5305162
2018.06.22 03:29:36.286 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3318 наносекунд, контрольная сумма = 5305162
2018.06.22 03:29:37.033 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 28   наносекунд, контрольная сумма = 5341596
2018.06.22 03:29:37.036 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3323 наносекунд, контрольная сумма = 5341596
2018.06.22 03:29:37.667 wBarShift (EURUSD,M1)   Время выполнения wBarShift = 30   наносекунд, контрольная сумма = 5367340
2018.06.22 03:29:37.671 wBarShift (EURUSD,M1)   Время выполнения iBarShift = 3819 наносекунд, контрольная сумма = 5367340
附加的文件:
wBarShift.mq5  5 kb
 
哇,显然,改用内置功能真的会缩短测试器中 EA 的工作时间...
 

修复。如果超出现有历史记录,就会返回错误的位置:

void OnStart()
  {
   datetime tm=StringToTime("2000.01.01");
   int pos=fBarShift(Symbol(),Period(),tm);
   double open[];
   Print(CopyOpen(Symbol(),Period(),pos,1,open));
   ArrayPrint(open);
  }

结果:

2020.03.13 13:35:50.729 test2 (EURUSD,M1)       -1
在这种情况下,fBarShift() 函数会返回总的条数,这不是一个正确的位置。
 
从代码来看,没有搜索所需的条形图,它是计算出来的。如果历史记录被破坏了呢?
 
Aliaksandr Hryshyn:

修复。如果超出现有历史记录,就会返回错误的位置:

结果:

2020.03.13 13:35:50.729 test2 (EURUSD,M1)       -1
在这种情况下,fBarShift() 函数会返回条形图 的总数,这不是正确的位置。


我不明白,它应该返回-1。

 
Aliaksandr Hryshyn:
从代码来看,没有搜索所需的条形图,它是计算出来的。如果历史记录被破坏了呢?

你说的 "根据代码判断 "是什么意思?

这只是你的想象,还是你已经深入研究过了?

那是很久以前的事了,但我记得,只有在适当的时候,也就是历史记录 100%没有破损、没有漏洞的时候,才会进行计算。这一点很容易通过检查条形图之间的时间差来验证。这样做的代价是速度的提高。如果你不相信我的话,可以检查一下。

现在,该代码比标准iBarShift 快,但并不明显(20-50%,之前快 10 倍)。MQ 已经修复了代码。因此我们可以说,这段代码已经不再重要了。

 
Nikolai Semko:


我不明白,它应该返回 -1 才对。

这是CopyOpen() 函数的返回代码

Print(CopyOpen(Symbol(),Period(),pos,1,open));

这里缺少第四个参数:

int pos=fBarShift(Symbol(),Period(),tm);
 
Nikolai Semko:

什么叫 "根据代码判断"?

这只是你的想象,还是你已经深入研究过了?

那是很久以前的事了,但我记得,只有在适当的时候才会有计算,也就是说,当历史100%没有中断,没有漏洞的时候。这一点很容易通过检查条形图之间的时间差来验证。这样做的代价是速度的提高。不相信的话,可以去看看。

现在这段代码比标准的 iBarShift 快,但并不明显(20-50%,之前快 10 倍)。MQ 已经修复了代码。因此我们可以说,这段代码已经不再重要了。

我使用了第一页的代码。没有循环,因此只有计算(不包括愚蠢的变体)。我不是说它错了,除了一个例外,其他都是正确的。

 
Aliaksandr Hryshyn:

我使用了第一页的代码。没有循环,所以只有计算(不包括愚蠢的变体)。我不是说它错了,除了一个例外,其他都是正确的。

这里不需要循环,因为使用的是标准 Bars() 函数,算法的本质是通过计算静态变量 中以前调用函数的存储数据,尽量减少对该函数的使用。

我修正了一个错误(将 fBarShift 函数中的 - 改为 +)。这个错误在我的代码中已经解决了,但我一定是忘了发布。已更新。版本 1.04。

这段代码的目的是解决 Bars() 函数中的错误。速度的提高只是 "副 "效应。现在,这个错误已不复存在,速度也有了显著提高。因此,现在使用此库毫无意义。