Analog zu iBarShift - Seite 12

 
Nikolai Semko :

Sie sagten, dass alles in MQL4 funktionieren sollte.

Dieses Skript kann aber auch in MQL5 ausgeführt werden

Bei exact=True und zukünftiger Zeit sollten Sie -1 zurückgeben

Mein Skript hat auch einen seltsamen Fehler gefunden:

Dieser Fehler wird durch diese Prüfung bestätigt:

Ich hatte also doch Recht, dass es in Ihrem Algorithmus anormale Situationen gibt.

Es ist schön, dass Sie den Fehler endlich gefunden haben

Ich werde es mir ansehen, danke.

 

Guten Abend zusammen. Vielleicht verstehe ich etwas falsch, aber trotzdem - es ist nicht ganz klar, was an der Standardfunktion falsch ist, die bereits am Anfang von Bars() vorgeschlagen wurde. Ich benutze es ständig und es hat keine Probleme verursacht. Das einzige Problem ist, dass Sie bei der Verwendung von TimeCurrent() auf "array out of range" oder negative Werte stoßen können, aber dann müssen Sie eine Prüfung dafür durchführen. Beispiele:

//найти бар на котором продали
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:

Guten Abend zusammen. Vielleicht verstehe ich etwas falsch, aber trotzdem - es ist nicht ganz klar, was an der Standardfunktion falsch ist, die bereits am Anfang von Bars() vorgeschlagen wurde. Ich benutze es ständig und es hat keine Probleme verursacht. Das einzige Problem ist, dass Sie bei der Verwendung von TimeCurrent() auf "array out of range" oder negative Werte stoßen können, aber dann müssen Sie eine Prüfung dafür durchführen. Beispiele:

Nach der Zahl 32000000000 zu urteilen, ist dies auch meine Kreation. UINT_MAX ist einfach kürzer und sieht solider aus. ))

Der Punkt ist, dass diese Variante korrekter ist, wie sich herausstellt:

Bars(Symb,TimeFrame,time+1,UINT_MAX);

statt

Bars(Symb,TimeFrame,time,UINT_MAX)-1;

es gibt fast keinen äußeren Unterschied. Aber die obere Variante wiederholt sehr genau die Standardfunktion iBarShift von MQL4

 
Nikolai Semko:

Nach der Zahl 32000000000 zu urteilen, ist dies auch mein Werk. UINT_MAX sieht einfach kürzer und solider aus. ))

Der Punkt ist, dass diese Variante korrekter ist, wie sich herausstellt:

statt

es gibt fast keinen äußeren Unterschied. Aber die obere Variante wiederholt sehr genau die Standardfunktion iBarShift von MQL4.

Welches ist also das einfachste und das richtige?

 
Vitaly Muzichenko:

Was ist also das Einfachste und Richtigste, was man tun kann?

So weit diese Variante, aber jetzt möchte ich sie ergänzen, um den Fehler des Einfrierens der Barrenfunktion zu umgehen, über den ich bereits an den Service Desk berichtet habe.

Der Kern dieses Fehlers ist, dass wenn in der Funktion Bars sowohlstart_time als auchstop_time innerhalb eines Balkens liegen oder in der Zukunft (rechts vom Null-Balken), dann bleibt diese Funktion für mehr als 10 Sekunden hängen.

Vielleicht mache ich später eine richtige, schnellere, aber umständlichere Version.

 

Ich habe beschlossen, einen anderen Weg zu gehen.
Ich werde iBarShift nicht überarbeiten, aber ich werde die fehlerhafte Funktion Bars überarbeiten.

Und die neue iBars-Funktion wird nicht nur den Schluckauf-Bug umgehen, sondern auch schneller sein als die ursprünglichen Bars.

Andere werden diese Funktion nutzen können, und die bereits vorhandenen Algorithmen werden schneller funktionieren.

Ich brauche einfach Zeit. Ich werde erst einen Tag später dazu in der Lage sein.

 
Nikolai Semko:

Ich habe beschlossen, einen anderen Weg einzuschlagen.
Ich werde iBarShift nicht überarbeiten, aber ich werde die fehlerhafte Funktion "Balken" überarbeiten.

Und die neue iBars-Funktion wird nicht nur den Schluckauf-Bug umgehen, sondern auch schneller sein als die ursprünglichen Bars.

Andere werden diese Funktion nutzen können, und die bereits vorhandenen Algorithmen werden schneller funktionieren.

Ich brauche einfach Zeit. Das wird frühestens in einem Tag zu schaffen sein.

Sehr gut! Ich freue mich darauf!

 
Nikolai Semko:

Aus all den Analysen, die ich durchgeführt habe, können wir schließen, dass dieses vollständige Analogon des 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);
  }

ist bei weitem die korrekteste, gleichzeitig die schnellste und mit dem einfachsten und kürzesten Algorithmus.

Es ist nett, aber etwas verwirrt mich...

wird es testen müssen )

 

Die iBars-Funktion ist recht umständlich, aber ich empfehle sie trotzdem anstelle der regulären Bars zu verwenden, bis MQ den Hänger in der Funktion behoben hat.

Der iBar bleibt hängen, obwohl er logischerweise 0 zurückgeben sollte. In der Regel wird sie für mehr als 10 Sekunden zurückgegeben. In MQL4 gibt es keinen solchen Fehler.

Bei den meisten Aufgaben wird iBars schneller arbeiten als die regulären Bars, da es nicht nur den Fehler vermeidet, sondern auch versucht, die Bars- und SeriesInfoInteger-Funktionen wann immer möglich nicht zu verwenden, da der Algorithmus die vorherigen Werte speichert.

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

Ich habe diese Funktion auf und ab getestet. Es scheint eine vollständige Kopie von Bars zu sein.

Vielleicht lässt sich das auf elegantere Weise bewerkstelligen. Wenn Sie einen Wunsch haben, sind Sie willkommen. Wenn Sie Fehler finden, werden wir sie beheben.

Also...

Dann hat die vollständige Analogie der Funktion iBarsShift die folgende Form:

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

Und die Variante ohne letzten Parameter, die in der überwiegenden Mehrheit der Fälle verwendet wird, hat diese Form:

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

Indikator, der die Leistung der iBars-Funktion im Vergleich zu den eingebauten Bars und der iBarShift-Funktion von @Alain Verleyen zeigt
Ausführungszeit der Funktion in Mikrosekunden.


Dateien: