iBarShiftのアナログ - ページ 3

 
Vasiliy Pushkaryov:

これがその台本です。

ハングアップしてしまうんです。強制的にチャートから外すと結果が出る。

だから、試してみたんです。だから、お薦めしたんです。でも、使ってみて自分に合っているのだから、考えは変えないよ。

ごめんね、バシリ。私はあなたを誤解していました。ただ、運転中にあなたの投稿を素早く読みました。最後のパラメータ、32000000000の ことかと思いきや、tパラメータのことだったんですね。はい、確かに。これは、オリジナルのMQL4 iBarShift()と結果が異なる唯一のケースです。しかし、バーがゼロであることが明らかな場合に、この関数を使って現在の時点、すなわちTimeCurrent() からバーの数(またはバーインデックス)を取得しようとするのは非常に奇妙なことです。一般に、TimeCurrent()Bars() 関数が1を出さずに0を出すのは不思議です。しかし、標準のBars()関数を使用したために何かがハングアップすることはありえず、特にスクリプトがPrint()をチェックしたので、すなわち、すべてがOKである。
Vasilyさん、私はiBarShiftアナログの他の実装を軽視したいわけではありません。そして、この構造はiBarShiftの代用としてではなく、単に指定した時刻のバーのインデックスを求める機能として使われており、普遍性という意味がよくわかりません。また、時間的なコストが高くなるため、上記の機能を全て使うのは合理的ではないと思います。(ドーシャパウダーのCMを思い出してください)。この関数を使うと、大きなサイクルが発生することが非常に多く、プログラムの実行時間が大幅に増えてしまうのですが、私は実行時間に対してひどく貪欲なんです。いろいろな関数の実行時間を計算する実験をしましたが(私だけでなく、前の記事も参照)、このオプションが一番速いのは間違いないです。最速と位置づけられるこの変形版 でも、(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を返します。したがって、1時間足のタイムフレームの02時5分に相当する時間をstart_time パラメータとして渡し、2時に始まったバーを検証したい場合は、CopyTime() でバー開始時間(02時0分)を得なければなりません。そうで なければ、関数Bars() このバーを無視 します。

例えば、時刻が3時30分の場合、1時間足のTFでは、時刻2時5分はインデックス1のバーを指すと理解しています。 2ページ目のどの関数も、このインデックスを返しません。この修正により、Renat Akhtyamovの 関数は私が期待したとおりの結果を返してくれました。

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を返します。したがって、1時間足のタイムフレームの02時5分に相当する時間をstart_time パラメータとして渡し、2時に始まったバーを検証したい場合は、CopyTime() でバー開始時間(02時0分)を得なければなりません。そうで なければ、関数Bars() このバーを無視 します。

例えば、現在が3時30分の場合、1時間足では2時5分がインデックス1のバーを指すと理解しています。 このインデックスは2ページ目のどの関数でも返されません。この修正により、Renat Akhtyamovの 関数は私が期待したとおりの結果を返してくれました。

インデックス検索関数の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:

どの程度難解なコードなのか、私にはよくわからないので聞いてみます。チャートが全日制でない場合、コードは動作しますか?

質問の本質が理解できない。言い方を変えれば

チャートは、最初の1秒を除いて、常に一日中ではありません。

どのような時間軸の話なのでしょうか?1日?

また、確認することを妨げるものは何ですか?

コードは私のものではなく、簡略化して高速化しただけです。

前回のメッセージで、PERIOD_W1とPERIOD_MN1について 追記しました。

アラン・ヴェルリーンの ものも含め、これまでのアルゴリズムはすべて異常な状況になっています。

iBarShift MQL4の完全なアナログを作ることもできますが、コードがかなり面倒になりますし、意味がないと思います。

 
Nikolai Semko:

質問の意味がわからない。言い方を変えれば

チャートは、最初の1秒を除いて、常に一日中ではありません。

TFってなんだ?1日?

また、確認することを妨げるものは何ですか?

コードは私のものではなく、簡略化して高速化しただけです。

前回のメッセージで、PERIOD_W1とPERIOD_MN1について 追記しました。

アラン・ヴェルリーンの ものも含め、これまでのアルゴリズムはすべて異常な状況になっています。

iBarShift MQL4の完全なアナログを作ることもできますが、コードが非常に面倒になり、その意味がわかりません。

というのも、ある状況下でコードが機能するかどうかを確実に知る必要があり、そうでなければ、誰かがミスをしたときにそれを責めるのは正しくないからです。

1日に14時間あるとします(1時間ごとに相場がない場合はそれ以下)、M1チャートを持っていて、前日のM15のバーのシフトを知る必要があります。つまり、1時間に45分とか、1日に14時間とか、時間・スイッチングが落ちても、すべて正しく動作するのでしょうか?