Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 134

 
Einfache Sortierung einer Reihe von Strukturen
#property strict

// Сортировка массива структур и указателей на объекты по (под-) полю/методу.
#define  ArraySortStruct(ARRAY, FIELD)                                            \
{                                                                                \
  class SORT                                                                     \
  {                                                                              \
  private:                                                                       \
    template <typename T>                                                        \
    static void Swap( T &Array[], const int i, const int j )                     \
    {                                                                            \
      const T Temp = Array[i];                                                   \
                                                                                 \
      Array[i] = Array[j];                                                       \
      Array[j] = Temp;                                                           \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
    template <typename T>                                                        \
    static int Partition( T &Array[], const int Start, const int End )           \
    {                                                                            \
      int Marker = Start;                                                        \
                                                                                 \          
      for (int i = Start; i <= End; i++)                                         \
        if (Array[i].##FIELD <= Array[End].##FIELD)                              \
        {                                                                        \
          SORT::Swap(Array, i, Marker);                                          \
                                                                                 \
          Marker++;                                                              \
        }                                                                        \
                                                                                 \
       return(Marker - 1);                                                       \
    }                                                                            \
                                                                                 \
    template <typename T>                                                        \
    static void QuickSort( T &Array[], const int Start, const int End )          \
    {                                                                            \
      if (Start < End)                                                           \
      {                                                                          \
        const int Pivot = Partition(Array, Start, End);                          \
                                                                                 \
        SORT::QuickSort(Array, Start, Pivot - 1);                                \
        SORT::QuickSort(Array, Pivot + 1, End);                                  \
      }                                                                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
                                                                                 \
  public:                                                                        \
    template <typename T>                                                        \ 
    static void Sort( T &Array[], int Count = WHOLE_ARRAY, const int Start = 0 ) \
    {                                                                            \
      if (Count == WHOLE_ARRAY)                                                  \
        Count = ::ArraySize(Array);                                              \
                                                                                 \
      SORT::QuickSort(Array, Start, Start + Count - 1);                          \
                                                                                 \
      return;                                                                    \
    }                                                                            \
  };                                                                             \
                                                                                 \
  SORT::Sort(ARRAY);                                                             \
}


Anmeldung

void OnStart()
{
  MqlRates Rates[];
  
  CopyRates(_Symbol, PERIOD_CURRENT, 0, 5, Rates); // Взяли бары
  
  Print("\nБары без сортировки - как получили.");
  ArrayPrint(Rates);
  
  Print("\nСортируем по open-цене.");
  ArraySortStruct(Rates, open);
  ArrayPrint(Rates);

  Print("\nСортируем по high-цене.");
  ArraySortStruct(Rates, high);
  ArrayPrint(Rates);

  Print("\nСортируем по времени.");
  ArraySortStruct(Rates, time);
  ArrayPrint(Rates);
}


Ergebnis

Бары без сортировки - как получили.
                 [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
[0] 2019.05.01 14:00:00 0.94437 0.94496 0.94420 0.94494           985       12             0
[1] 2019.05.01 15:00:00 0.94494 0.94512 0.94313 0.94322          2593       13             0
[2] 2019.05.01 16:00:00 0.94322 0.94350 0.94272 0.94272          2020       12             0
[3] 2019.05.01 17:00:00 0.94272 0.94439 0.94267 0.94433          3922       11             0
[4] 2019.05.01 18:00:00 0.94434 0.94474 0.94423 0.94437          1004       13             0

Сортируем по open-цене.
                 [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
[0] 2019.05.01 17:00:00 0.94272 0.94439 0.94267 0.94433          3922       11             0
[1] 2019.05.01 16:00:00 0.94322 0.94350 0.94272 0.94272          2020       12             0
[2] 2019.05.01 18:00:00 0.94434 0.94474 0.94423 0.94437          1004       13             0
[3] 2019.05.01 14:00:00 0.94437 0.94496 0.94420 0.94494           985       12             0
[4] 2019.05.01 15:00:00 0.94494 0.94512 0.94313 0.94322          2593       13             0

Сортируем по high-цене.
                 [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
[0] 2019.05.01 16:00:00 0.94322 0.94350 0.94272 0.94272          2020       12             0
[1] 2019.05.01 17:00:00 0.94272 0.94439 0.94267 0.94433          3922       11             0
[2] 2019.05.01 18:00:00 0.94434 0.94474 0.94423 0.94437          1004       13             0
[3] 2019.05.01 14:00:00 0.94437 0.94496 0.94420 0.94494           985       12             0
[4] 2019.05.01 15:00:00 0.94494 0.94512 0.94313 0.94322          2593       13             0

Сортируем по времени.
                 [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
[0] 2019.05.01 14:00:00 0.94437 0.94496 0.94420 0.94494           985       12             0
[1] 2019.05.01 15:00:00 0.94494 0.94512 0.94313 0.94322          2593       13             0
[2] 2019.05.01 16:00:00 0.94322 0.94350 0.94272 0.94272          2020       12             0
[3] 2019.05.01 17:00:00 0.94272 0.94439 0.94267 0.94433          3922       11             0
[4] 2019.05.01 18:00:00 0.94434 0.94474 0.94423 0.94437          1004       13             0
 
fxsaber:
Praktisches Sortieren einer Reihe von Strukturen


      if (Count == WHOLE_ARRAY)                                                  \
        Count = ::ArraySize(Array) - Start; 

Gelb hat die fehlenden Dinge hervorgehoben, und es scheint mir, dass es in der Reihenfolge der Argumente besser ist, mit Start und dann Count zu beginnen.

Übrigens ist es wahrscheinlich sinnvoller, Arrays von Strukturen nach Indizes zu sortieren (ich meine die Neuordnung der Indizes, nicht der Strukturen selbst), aber das hängt natürlich von der Größe der Struktur ab.

 
Alexey Navoykov:

Ich habe das, was fehlte, gelb hervorgehoben.

Danke, ich habe es übersehen.

Ich denke, es ist besser, mit Start und dann Count in der Reihenfolge der Argumente zu beginnen.

Das Signal ist dem MT4-ArraySort entlehnt.

Übrigens wäre es wahrscheinlich sinnvoller, Arrays von Strukturen nach Indizes zu sortieren (ich meine die Umordnung der Indizes, nicht der Strukturen selbst).

Das war das erste, was mir in den Sinn kam, aber ich habe es aufgegeben. Denn es erfordert die Verwendung von ArrayCopy des ursprünglichen Arrays und des Arrays der Indizes. Und das ist ein zusätzlicher Speicher. Und die Maschine kann sich eine solche Sortierung eines Arrays von z.B. Millionen von MqlTick-Elementen nicht leisten.

Wir hätten zwei Sortiervarianten einbauen können, aber das habe ich im Quellcode nicht getan. Bei der Demonstration sind vielleicht die Benutzerfreundlichkeit und die Art der Umsetzung am wichtigsten. Nach dem Studium ist es bereits klar, wie Sie Ihre Bedürfnisse ergänzen und ein Analogon für andere Funktionen von Arrays mit Strukturen (ArrayMaximum, etc.) erstellen können.

ArraySort - Операции с массивами - Справочник MQL4
ArraySort - Операции с массивами - Справочник MQL4
  • docs.mql4.com
//| Script program start function                                    |
 
fxsaber:
Praktisches Sortieren einer Reihe von Strukturen


Anmeldung


Ergebnis

Wie kann man diesen Code in eine einfache Klasse umwandeln, ohne #define zu verwenden?

 
Vladimir Pastushak:

Wie kann man diesen Code in eine einfache Klasse umwandeln, ohne #define zu verwenden?

Das können Sie nicht. ArraySortStruct soll als Funktion verwendet werden, ohne dass man sich damit beschäftigt, wie sie organisiert ist.

Werfen Sie einfach ein paar enludniks in den Quellcode und vergessen Sie es. Danach ist eine wirklich praktische "Funktion" für jeden Anfänger (und nicht nur für ihn) immer zur Hand.

 
Folks, werfen in einem Verweis, wenn es eine solche, brauchen die Flagge der Zeit der Eröffnung des Abends (zusätzliche) Handelssitzung auf FORTS MOEX, und wie alle sah durch, aber nicht finden, wollen nicht eine Krücke Definition um 19:00 oder 19:05 Uhr zu schreiben wird Handelssitzung öffnen
 

Eine Zufallszahl von 0 bis max mit gleicher Wahrscheinlichkeit:

uint get_rand(uint max)
{
   static bool f = false;
   if ( ! f ) {
      f = true;
      srand(GetTickCount());
   }  
   uint limit = (max+1) * ((32767+1) / (max+1));
   uint val;
   while ((val = rand()) >= limit);
   return val % (max+1);
}
 
Renat Fatkhullin:

Der Multi-Buffer ist großartig, um den Editor zu beschleunigen und ist sicher.

Es schreibt nichts auf die Festplatte und behält die Daten nur im Speicher.

Bei welcher Bewertung kann ich ein Bild auf der Website einfügen?
 
Vict:

Eine Zufallszahl von 0 bis max mit gleicher Wahrscheinlichkeit:

Ihre Funktion ist zu 100 % gleichwertig:

uint get_rand(uint max)
  {
   static bool f = true;
   if (f) {f = ~f; srand(GetTickCount());} 
   return rand() % (max+1);
  }

weil erstens.

uint limit = (max+1) * (32767+1 / (max+1));

vereinfacht zu

uint limit = (max+1) * 32767+1; // т.е. при даже max=0 limit =32768

daher, zweitens

while ((val = rand()) >= limit);

wird immer nur einmal durchgeführt.

Komplexität ist eine detaillierte Erklärung der Einfachheit. ))

 
Nikolai Semko:

Ihre Funktion ist zu 100 % gleichwertig:

weil erstens.

vereinfacht zu

daher, zweitens

wird immer nur einmal durchgeführt.

Komplexität ist eine detaillierte Erklärung der Einfachheit. ))

Sie sind sehr rücksichtsvoll, vielen Dank. Ich habe einen Fehler gemacht, ich habe keine Klammern gesetzt, also würde ich die Funktion "unfair" verwenden.

SZZ: hat den ursprünglichen Beitrag korrigiert.

Grund der Beschwerde: