Analog zu iBarShift - Seite 3

 
Vasiliy Pushkaryov:

Hier ist das Drehbuch.

Er bleibt einfach hängen. Das gewaltsame Entfernen aus dem Diagramm liefert das Ergebnis.

Ich habe es also ausprobiert, deshalb habe ich es Ihnen empfohlen. Aber da Sie es benutzt haben und es Ihnen gefällt, werde ich meine Meinung nicht ändern.

Es tut mir leid, Vassili. Ich habe Sie missverstanden. Ich habe Ihren Beitrag gerade schnell gelesen, als ich unterwegs war. Ich dachte, es ginge um den letzten Parameter, wo ich32000000000 habe, aber es stellte sich heraus, dass Sie den Parameter t meinten. Ja, in der Tat - es ist der einzige Fall, wo das Ergebnis unterscheidet sich von der ursprünglichen MQL4 iBarShift(). Es ist jedoch sehr seltsam, diese Funktion zu verwenden, um die Anzahl der Balken (oder den Balkenindex) ab dem aktuellen Zeitpunkt, d. h.TimeCurrent(), zu ermitteln, wenn klar ist, dass der Balken Null ist. Im Allgemeinen ist es seltsam, dass die FunktionBars() beiTimeCurrent() 0 und nicht 1 produziert. Formal ist es ein Fehler der Entwickler, obwohl es darauf ankommt. Aber es kann nicht sein, dass etwas wegen der Verwendung der Standardfunktion Bars() hängen bleibt, zumal das SkriptPrint() überprüft hat, d. h. alles ist in Ordnung.
Verstehen Sie, Vasily, ich möchte andere Implementierungen von iBarShift analog nicht herabsetzen, es ist nur so, dass ich persönlich genau diese Konstruktion(Bars(NULL,0,t,32000000000)-1;) verwende, weil sie die schnellste ist. Und diese Konstruktion wird nicht als Ersatz für iBarShift verwendet, sondern einfach als Funktion, um einen Index eines Balkens zu einem bestimmten Zeitpunkt zu finden, und ich verstehe nicht, was Sie mit Universalität meinen. Und ich glaube nicht, dass es sinnvoll ist, wegen des höheren Zeitaufwands alle oben genannten Funktionen zu verwenden. (Erinnern Sie sich an die Werbung für Dosya-Pulver). Die Sache ist die, dass die Verwendung dieser Funktion sehr oft in großen Zyklen erfolgt, was die Laufzeit des Programms erheblich verlängert, und ich bin furchtbar gierig nach Laufzeit. Ich habe Experimente zur Berechnung der Laufzeit verschiedener Funktionen durchgeführt (und nicht nur ich, siehe vorherigen Beitrag) und diese Option ist definitiv die schnellste. Auch diese Variante, die als die schnellste positioniert ist, ist dieselbe, aber das(Bars(NULL,0,t,32000000000)-1;) Konstrukt ist noch einfacher. Natürlich bleibt es jedem selbst überlassen, was er verwendet.

Auf jeden Fall danke ich Ihnen für Ihre substanzielle Bemerkung.

 
Nikolai Semko:

Aber es ist sehr seltsam, wenn man versucht, diese Funktion zu verwenden, um die Anzahl der Balken (oder den Index eines Balkens) ab dem aktuellen Zeitpunkt zu erhalten, d.h.TimeCurrent(), wenn bereits klar ist, dass der Balken Null ist. Es ist seltsam, dass die FunktionBars() beiTimeCurrent() 0 statt 1 ergibt.

TimeCurrent() war nur ein Spezialfall, den ich zur Hand hatte.

Ich habe diese Anmerkung zur Funktion Bars() jetzt genauer gelesen:

"Bei der Abfrage der Anzahl der Takte in einem bestimmten Datumsbereich werden nur die Takte berücksichtigt, deren Öffnungszeit in diesen Bereich fällt. Wenn der aktuelle Wochentag beispielsweise Samstag ist, gibt die Funktion bei der Abfrage der Anzahl der wöchentlichen Balken mit start_time=lastTuesday und stop_time=lastFriday den Wert 0 zurück, da die Eröffnungszeit des wöchentlichen Zeitrahmens immer auf einen Sonntag fällt und kein wöchentlicher Balken in den angegebenen Bereich fällt".

Da TimeCurrent() fast immer später als die Eröffnungszeit des aktuellen Balkens ist, gibt die Funktion Bars() den Wert 0 zurück. Wenn wir also als Parameter start_time die Zeit 02:05 auf dem stündlichen Zeitrahmen übergeben und den um 2 Uhr begonnenen Balken validieren wollen, müssen wir die Eröffnungszeit des Balkens (02:00:00) über CopyTime() ermitteln. Andernfalls wird die Funktion Balken() diesen Balken ignorieren.

Wenn z.B. die Uhrzeit 3:30 ist, bezieht sich die Uhrzeit 2:05 im stündlichen TF auf den Balken mit dem Index 1. Keine der Funktionen auf der zweiten Seite gibt diesen Index zurück. Mit dieser Korrektur ergab die Funktion von Renat Akhtyamov das, was ich erwartet hatte.

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

Ich füge ein Skript mit 4 Optionen für Indexnachschlagefunktionen bei, das ich als Test verwendet habe.

Dateien:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

Die FunktionTimeCurrent() ist nur in einem speziellen Fall anzutreffen.

Ich habe diese Anmerkung zur Funktion Bars() jetzt genauer gelesen:

"Bei der Abfrage der Anzahl der Takte in einem bestimmten Datumsbereich werden nur die Takte berücksichtigt, deren Öffnungszeit in diesen Bereich fällt. Wenn der aktuelle Wochentag beispielsweise Samstag ist, gibt die Funktion bei der Abfrage der Anzahl der wöchentlichen Balken mit start_time=lastTuesday und stop_time=lastFriday den Wert 0 zurück, da die Eröffnungszeit des wöchentlichen Zeitrahmens immer auf einen Sonntag fällt und kein wöchentlicher Balken in den angegebenen Bereich fällt".

Da TimeCurrent() fast immer später als die Eröffnungszeit des aktuellen Balkens ist, gibt die Funktion Bars() den Wert 0 zurück. Wenn wir also als Parameter start_time die Zeit 02:05 auf dem stündlichen Zeitrahmen übergeben und den um 2 Uhr begonnenen Balken validieren wollen, müssen wir die Eröffnungszeit des Balkens (02:00:00) über CopyTime() ermitteln. Andernfalls wird die Funktion Balken() diesen Balken ignorieren.

D.h., wenn es jetzt 3:30 Uhr ist, verstehe ich, dass sich im stündlichen Zeitrahmen 2:05 Uhr auf den Balken mit dem Index 1 bezieht. Dieser Index wird von keiner Funktion der 2. Seite zurückgegeben. Mit dieser Korrektur ergab die Funktion von Renat Akhtyamov das, was ich erwartet hatte.

Ich füge ein Skript mit 4 Optionen für Indexnachschlagefunktionen bei, das ich als Test verwendet habe.

Natürlich muss ich die Probezeit bestehen. Ich habe vergessen, das zu präzisieren.
 
Ich verstehe nicht, warum es diese Funktion in SB noch nicht gibt.
 
transcendreamer:
Ich verstehe nicht, warum diese Funktion in der SB immer noch nicht verfügbar ist.

Ich habe alle Varianten ausprobiert, die korrekteste ist von Alain Verleyen.
(getestet an einem komplexen Indikator mit vielen Objekten)
 
Taras Slobodyanik:

Ich habe alle Varianten ausprobiert, die korrekteste ist von Alain Verleyen.
(getestet an einem komplexen Indikator mit vielen Objekten)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • Stimmen: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

Meiner Meinung nach ist die Verwendung der FunktionSeriesInfoInteger überflüssig, da sie nicht frei ist.

War:

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

Wurde:

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

Der Geschwindigkeitsgewinn beträgt etwa das Eineinhalbfache.

Und es scheint die schnellste Option zu sein. Richtig, der letzte ParameterExact ist eine Fälschung, die entfernt werden kann. Meiner Meinung nach ist das aber nicht notwendig. Ich persönlich bin noch nie auf Aufgaben gestoßen, bei denen wirExact= true benötigten.

Aber wenn jemand es braucht, kommt er ohne CopyTime nicht aus und es ist besser, dieVariante von @Alain Verleyen zu verwenden.

SZY: Ich habe überflüssige Aufrufe der FunktionPeriodSeconds umgangen, wenn sich TF seit dem letzten Aufruf nicht geändert hat. Der Zuwachs ist zwar schwach - ein paar Prozent, aber immerhin.

Und noch eine Bemerkung: Konstruktion

time-=time%PerSec;
funktioniert nicht korrekt mit PERIOD_W1 und PERIOD_MN1, weil sie am 1. Januar 1970 beginnt, was kein Montag, sondern ein Donnerstag ist. Und jeder Monat hat eine andere Anzahl von Sekunden.
 
Nikolai Semko:

Meiner Meinung nach ist die Verwendung der FunktionSeriesInfoInteger überflüssig, da sie nicht frei ist.

War:

Wurde:

Der Geschwindigkeitsgewinn beträgt etwa das Eineinhalbfache.

Und es scheint die schnellste Option zu sein. Richtig, der letzte ParameterExact ist eine Fälschung. Aber wenn Sie mich fragen, brauchen Sie das nicht.

Oder liege ich da falsch?

SZY: Ich habe auch überflüssige Aufrufe der FunktionPeriodSeconds umgangen, wenn sich TF seit dem letzten Aufruf nicht geändert hat. Der Gewinn ist wirklich gering - ein paar Prozent, aber immerhin.

Ich verstehe nicht, wie clever dieser Code ist, deshalb möchte ich Ihnen eine Frage stellen. Funktioniert der Code auch, wenn die Karte nicht ganztägig ist?

 
Aleksey Vyazmikin:

Wie kompliziert der Code ist, ist mir nicht klar, also frage ich nach. Funktioniert der Code auch, wenn die Karte nicht ganztägig ist?

Ich verstehe den Kern der Frage nicht. Anders formuliert.

Das Diagramm ist immer nicht ein ganzer Tag, außer in der ersten Sekunde des Tages.

Über welchen Zeitrahmen sprechen wir? Ein Tag?

Und was hindert Sie daran, das zu überprüfen?

Der Code ist nicht von mir, ich habe ihn nur vereinfacht und schneller gemacht.

In meiner vorherigen Nachricht habe ich einen Zusatz überPERIOD_W1 und PERIOD_MN1 gemacht.

Alle bisherigen Algorithmen, auch der von @Alain Verleyen, weisen anormale Situationen auf.

Sie können ein vollständiges Analogon von iBarShift MQL4 erstellen, aber der Code wird ziemlich umständlich sein, und ich sehe keinen Sinn darin.

 
Nikolai Semko:

Ich verstehe nicht, worauf die Frage abzielt. Anders formuliert.

Das Diagramm ist immer nicht ein ganzer Tag, außer in der ersten Sekunde des Tages.

Von welcher TF sprechen wir? Ein Tag?

Und was hindert Sie daran, das zu überprüfen?

Der Code ist nicht von mir, ich habe ihn nur vereinfacht und schneller gemacht.

In meiner vorherigen Nachricht habe ich einen Zusatz überPERIOD_W1 und PERIOD_MN1 gemacht.

Alle bisherigen Algorithmen, auch der von @Alain Verleyen, weisen anormale Situationen auf.

Sie können ein vollständiges Analogon von iBarShift MQL4 erstellen, aber der Code wird sehr umständlich sein, und ich sehe keinen Sinn darin.

Ich habe es nicht getestet, weil man sicher wissen muss, ob der Code in einer bestimmten Situation funktioniert, sonst ist es nicht korrekt, jemand anderem die Schuld zu geben, wenn er/sie einen Fehler gemacht hat.

Ich spreche von Situationen wie dieser: Nehmen wir an, ein Tag hat 14 Stunden (oder weniger, wenn es nicht stündlich Kurse gibt), ich habe ein M1-Diagramm und muss die Verschiebung eines Balkens auf M15 für den Vortag kennen. Funktioniert also alles korrekt, wenn ich 45 Minuten in einer Stunde oder 14 Stunden an einem Tag oder andere Zeit- bzw. Schaltabweichungen erhalte?