Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 235

 
Marat Sultanov #:
Früher war es möglich (auch in älteren Compiler-Builds), eine Klasse zu verwenden, bevor sie deklariert wurde:
Aber jetzt bekommen wir einen Fehler beim Kompilieren:
undefinierte Klasse 'A' kann nicht verwendet werden

Wenn es nicht mehr funktioniert, wäre es gut zu wissen, ob es richtig ist.

Wenn Sie Zeiger anstelle von Objekten erzeugen, funktioniert auch die alte Version.

 
fxsaber #:

Wenn es nicht mehr funktioniert, ist es gut zu wissen, ob es das Richtige ist, das zu tun.

Wenn Sie Zeiger anstelle von Objekten erzeugen, funktioniert auch die alte Version.

Toller Punkt und danke für den Tipp!

Ja, in der Tat, die Situation ist perfekt mit einem Zeiger gelöst:

class A;

class B
{
   public: A * a;
   public: int Val;
};

class A
{
   public: B * b;
   public: int Test() {return b.Val + 1;}
};

//+------------------------------------------------------------------+
//|                                                                                |
//+------------------------------------------------------------------+
void OnStart()
{
   B b;
   A a;
   
   b.a = GetPointer(a);
   b.a.b = GetPointer(b);
   b.Val = 1;
   
   Print(b.a.Test());
}
 

Fans von schnellen Algorithmen. Diejenigen, die um Nanosekunden kämpfen :)


Aufgabe: Finden Sie den Zeitpunkt der Balkeneröffnung entsprechend der vorgegebenen Zeit und TF, wenn bekannt ist, dass der Balken zu diesem Zeitpunkt existiert. Zum Beispiel durch den Zeitpunkt der Eröffnungs- und Schlusspositionen.

Die meisten Programmierer werden eine Kombination aus iTime und iBarShift verwenden. Dies ist die langsamste Implementierung, zumal eine solche Implementierung einen aktuellen Verlauf der hochgeladenen Daten oder gekämmten Arrays erfordert. Außerdem kann dieser Ansatz zu Fehlern führen, wenn die erforderliche Historie nicht vorhanden ist.

Fortgeschrittene Programmierer werden dieses Problem mit der MqlDateTime-Struktur und der Funktion TimeToStruct() lösen. Dies ist keine schlechte Lösung und schnell genug.

Es gibt jedoch noch eine dritte Lösung, die um ein Vielfaches produktiver ist als die vorherige Lösung:

//+------------------------------------------------------------------+
// получает время открытия виртуального бара по входному времени и Таймфрейму, вне зависимости от того, существует реальный бар или нет.
// корректно считает только до 28.02.2100 !!!!
// не является заменой iBarShift!!! Не зависит от истории баров.  
datetime getStartTimeOfBarFast(ENUM_TIMEFRAMES tf, datetime t) {
   if (tf==0) tf=_Period;

   int ts=0;
   if (tf<PERIOD_MN1) {
      ushort i_tf= ushort(tf);
      uchar _i =uchar(i_tf>>14);
      int n = i_tf & 0x0FFF;
      ts = (_i==0)?n*60:(_i==1)?n*60*60:60*60*24*7;
   }
   if (tf<PERIOD_W1) return t-t%ts;
   if (tf==PERIOD_W1) return t-(t+4*24*60*60)%ts;
   else { // Period MN1
      static int dm[12] = {0,31,61,92,122,153,184, 214, 245, 275, 306, 337};
      static int last_days = 0;
      static datetime last_result = 0;
      int days = int(t/(24*60*60));
      if (last_days!=days) {
         last_days = days;
         int d1 = (days+306+365)%1461;
         int y = d1/365;
         datetime t1 = t - t%(24*60*60) - d1*24*60*60;
         int m = 0;
         if (d1==1460) {
            m=11;
            y--;
         };
         int d = d1-y*365+1;
         if (d!=31) if (d==276) m = 9;
            else m = int (d/30.68);
         if (m<0 || m>11) return -1;
         last_result = t1+y*365*24*60*60+dm[m]*24*60*60;
      }
      return last_result;
   }
}
//+------------------------------------------------------------------+

Die Hauptschwierigkeit bei diesem Algorithmus ist die Berechnung der Uhrzeit des Monatsanfangs (grün hervorgehoben). Bitte versuchen Sie nicht, die Funktionsweise des Algorithmus zu verstehen. Hier geht Magie vor sich, die das Ergebnis des Übergangs vom Einfachen zum Komplexen ist. Der umgekehrte Weg vom Komplexen zum Einfachen ist viel schwieriger zu bewältigen.

Der Leistungsgewinn ergibt sich auch aus dem Algorithmus, der die Sekunden eines Balkens aus der TF ermittelt, anstatt aus der Standardfunktion PeriodSeconds() - gelb hervorgehoben.


Ich füge ein Testskript bei, das die Leistung aller drei Methoden berechnet und vergleicht:

2023.11.14 12:15:29.145 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.14 12:15:29.146 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 21.20 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:29.146 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.10 наносекунд - Быстрый расчет
2023.11.14 12:15:29.147 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 142.00 наносекунд - Расчет через iBarShift
2023.11.14 12:15:29.147 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:34.226 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.14 12:15:34.227 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 19.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:34.227 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.70 наносекунд - Быстрый расчет
2023.11.14 12:15:34.228 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11987239507200, время выполнения 1 иттерации = 127.50 наносекунд - Расчет через iBarShift
2023.11.14 12:15:34.228 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_W1========
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:39.856 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:39.857 timeToStartMonth (EURUSD,M1)    контрольная сумма - 11997367833600, время выполнения 1 иттерации = 98.30 наносекунд - Расчет через iBarShift
2023.11.14 12:15:39.857 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:52.770 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.14 12:15:52.771 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000355999200, время выполнения 1 иттерации = 4.10 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:52.771 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000355999200, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:54.255 timeToStartMonth (EURUSD,M1)    контрольная сумма - 0, время выполнения 1 иттерации = 148466.50 наносекунд - Расчет через iBarShift
2023.11.14 12:15:54.255 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000391999920, время выполнения 1 иттерации = 3.60 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:15:58.759 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000391999920, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.14 12:15:59.864 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000017286960, время выполнения 1 иттерации = 110555.70 наносекунд - Расчет через iBarShift
2023.11.14 12:15:59.864 timeToStartMonth (EURUSD,M1)    ========================================================================

Die Prüfsumme mit iBarShift wird nicht übereinstimmen , da iBarShift mit echten Balken arbeitet. Die Prüfsumme stimmt nur bei den Zeitrahmen MN1 und W1 überein, da es in der Historie dieser Balken keine Löcher gibt.
Die Leistung ist höher, wenn Sie einen kleinen Zeitschritt in der Schleife verwenden (weniger als einen Tag), wenn der Algorithmus zu arbeiten beginnt, um frühere Berechnungen zu speichern:

2023.11.14 12:14:10.714 timeToStartMonth (EURUSD,M1)    =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.14 12:14:10.722 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 8.03 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:14:10.723 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.14 12:14:10.860 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 136.80 наносекунд - Расчет через iBarShift
2023.11.14 12:14:10.860 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:14:17.502 timeToStartMonth (EURUSD,M1)    =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.14 12:14:17.510 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 7.70 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:14:17.511 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.14 12:14:17.648 timeToStartMonth (EURUSD,M1)    контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 137.54 наносекунд - Расчет через iBarShift
2023.11.14 12:14:17.648 timeToStartMonth (EURUSD,M1)    ========================================================================


Überhöhte Werte für den Algorithmus über iBarShift (blau hervorgehoben) werden durch das Fehlen der notwendigen Historie oder der vom Array berechneten TFs verursacht, was deren Hochladen einleitet.
Nach dem Hochladen sieht das Ergebnis wie folgt aus:

2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000379996800, время выполнения 1 иттерации = 4.60 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:47:06.158 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000379996800, время выполнения 1 иттерации = 2.60 наносекунд - Быстрый расчет
2023.11.14 12:47:06.159 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000009103200, время выполнения 1 иттерации = 129.10 наносекунд - Расчет через iBarShift
2023.11.14 12:47:06.159 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000411199920, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 12:47:13.899 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000411199920, время выполнения 1 иттерации = 1.40 наносекунд - Быстрый расчет
2023.11.14 12:47:13.903 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000038634480, время выполнения 1 иттерации = 381.30 наносекунд - Расчет через iBarShift
2023.11.14 12:47:13.903 timeToStartMonth (EURUSD,M1)    ========================================================================

Dateien:
 
Nikolai Semko #:

Fans von schnellen Algorithmen. Diejenigen, die für Nanosekunden kämpfen :)

...

😮😲😳🥴🤪

...

ah ...

mmm....

oooh....

gkghm... Ich hätte nicht gedacht, dass meine einfache Frage so ausfallen würde.

Einfach so. Oh.

 
Artyom Trishkin #:

😮😲😳🥴🤪

...

ach ...

mmm.

ohhhh....

hm. Ich hätte nicht gedacht, dass meine einfache Frage so enden würde.

Oh.

Ja, Artem, du hast mich für eine Weile getäuscht.
Es war ein sportliches Interesse.
Ich hoffe, es wird jemandem nützlich sein, mich eingeschlossen. :))

 
Nikolai Semko #:

Ja, Artem, haben Sie mich für eine Weile betrogen.
Ich arbeitete an sportlichen Interesse.
Ich hoffe, es wird nützlich sein, jemanden, und mich unter anderem. :))

Natürlich wird es das. Großartig! Nochmals vielen Dank!

S.F. Das hat mich amüsiert: "zählt nur bis zum 28.02.2100 korrekt !!!!".

Und was machen wir danach?

 
Artyom Trishkin #:

Natürlich wird es sich als nützlich erweisen. Sehr gut. Nochmals vielen Dank!

S.F. Das hat mich amüsiert: "zählt nur bis zum 28.02.2100 korrekt !!!!".

Und was machen wir danach?

haha.
Ich bezweifle, dass dieser Algorithmus noch 75 Jahre lang gefragt sein wird. Quantencomputer werden wahrscheinlich schon die Welt beherrschen, mit einer völlig anderen Programmierung.
Um ehrlich zu sein, war es faul, den gregorianischen Kalender zu berücksichtigen. 2000 stand viel auf dem Spiel, 2100 ist es nicht mehr.

 
Nikolai Semko #:

haha.
Ich bezweifle, dass dieser Algorithmus noch 75 Jahre lang gefragt sein wird. Quantencomputer werden wahrscheinlich schon die Welt beherrschen, mit einer völlig anderen Programmierung.
Um ehrlich zu sein, war es faul, den gregorianischen Kalender vollständig zu berücksichtigen. 2000 stand viel auf dem Spiel, 2100 ist es nicht mehr.

Für MN kann man ein vorberechnetes Array verwenden, da ist fast nichts drin

Ln2(12 Monate * hundert Jahre)...11 if`'s und Vergleiche in binärer Suche, aber ohne andere Berechnungen.

 
Maxim Kuznetsov #:

Sie können ein vorberechnetes Array für MN verwenden, da es dort kaum Daten gibt.

Ln2(12 Monate * hundert Jahre)...11 if`'s und Vergleiche in binärer Suche, aber ohne andere Berechnungen.

Es gibt keine Schwierigkeiten. Ich weiß, wie man es implementiert.
Ich möchte nur nicht etwas machen, von dem ich zu 100% sicher bin, dass es nie nützlich sein wird.
 
Maxim Kuznetsov #:

Sie können ein vorberechnetes Array für MN verwenden, da es dort kaum Daten gibt.

Ln2(12 Monate * hundert Jahre)...11 if`'s und Vergleiche in binärer Suche, aber ohne andere Berechnungen.

ah, ich habe es zuerst falsch gelesen.
Nein, du liegst falsch. Die Leistungssteigerung wird nicht funktionieren. Sie werden immer noch in Berechnungen stecken bleiben. Und der Zugriff auf Array-Elemente verlangsamt den Algorithmus sehr stark.