iBarShiftのアナログ - ページ 12

 
Nikolai Semko :

MQL4ですべて動作するはず だと言っていましたね。

しかし、このスクリプトはMQL5でも実行可能です。

exact=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_timeとstop_timeの 両方が1つのバーの中にあるか、未来(ゼロバーの右側)にある場合、この関数が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機能はかなり面倒ですが、MQがハングアップのバグを修正するまでは、通常のBarsの代わりに使用することをお勧めします。

論理的には0を返すべきなのに、iBarがハングアップしてしまう。原則として10秒以上返します。MQL4にはそのようなバグはありません。

iBarsはバグを回避するだけでなく、以前の値を保存するアルゴリズムにより、可能な限りBars関数や SeriesInfoInteger関数を使用しないため、ほとんどのタスクにおいて、通常のBarsよりも速く動作します。

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

私はこの機能をあちこちでテストしてきました。バーズをフルコピーしているようです。

もしかしたら、もっとエレガントな方法でできるかもしれません。願望があれば、大歓迎です。エラーを発見した場合は、修正します。

それで...

そうすると、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);
  }

そして、最後のパラメータがない variant は、ほとんどの場合この形式になります。

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 氏提供
関数実行時間(マイクロ秒)。


ファイル: