ライブラリ: MT5 用の高速 iBarShift と Bars - ページ 2

 
Alexey Navoykov:

実際、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より10倍速い。

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() 関数はバーの 総数を返しますが、これは正しい位置ではありません。


これは正しい位置ではありません。

 
Aliaksandr Hryshyn:
コードから判断すると、必要なバーの検索はなく、計算されている。履歴が壊れた場合は?

コードで判断する」とはどういう意味ですか?

想像なのか、それともしっかり勉強したのか。

ずいぶん昔のことですが、確か適切な場合、つまり履歴が100%壊れておらず、穴がない場合にのみ計算があったように記憶しています。これは小節間の時間差をチェックすれば簡単に確認できる。その代償として、スピードが向上している。もし信じられないなら、試してみてほしい。

現在、このコードは標準のiBarShiftより 速くなっているが、著しくはない(20-50%、以前は10倍速かった)。すでにMQはコードを修正した。だから、このコードはもうあまり意味がないと言える。

 
Nikolai Semko:


私はそれを理解できない。

これはCopyOpen() 関数のリターン・コードである。

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

そして、ここには4番目のパラメータがありません:

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

コードで判断する」とは?

単なる想像なのか、それとも徹底的に研究したのか?

ずいぶん昔のことですが、確か適切なときだけ、つまり100%ヒストリーに切れ目がなく、穴がないときだけ計算があったように記憶しています。これは小節間の時間差をチェックすれば簡単に確認できる。その代償として、スピードが向上している。私の言うことが信じられないのであれば、試してみてください。

現在、このコードは標準のiBarShiftより速くなっているが、著しくはない(20-50%、以前は10倍速かった)。すでにMQはコードを修正した。だから、このコードはもうあまり意味がないと言える。

私は最初のページのコードを使った。サイクルはないので、計算だけです(愚かな変種を除く)。私はそれが間違っていると言っているのではなく、1つの例外を除いてすべてが正しいのです。

 
Aliaksandr Hryshyn:

最初のページのコードを使った。ループはないので、計算だけです(愚かな変形を除く)。間違っているとは言っていない。1つの例外を除いて、すべてが正しい。

なぜなら、標準のBars()関数が使用されており、アルゴリズムの本質は、静的変数に 以前の関数呼び出しの保存されたデータを使用して計算することにより、その使用を最小限に抑えることだからです。

エラーを1つ修正した(fBarShift関数の-を+に変更)。それは私のコードで修正されていることが判明したが、私はそれを投稿するのを忘れていたに違いない。更新。バージョン1.04。

このコードの目的は、Bars()関数にあったバグと戦うことだった。スピードアップは「副次的な」効果だった。今ではこのバグはなくなり、速度もかなり改善された。だから、このライブラリの意味はない。