Características del lenguaje mql5, sutilezas y técnicas - página 134

 
Clasificación sencilla de un conjunto de estructuras
#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);                                                             \
}


Aplicación

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


Resultado

Бары без сортировки - как получили.
                 [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:
Ordenación práctica de un conjunto de estructuras


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

El amarillo ha resaltado las cosas que faltan, y me parece que es mejor en orden de argumentos, primero Inicio, y luego Contar.

Por cierto, probablemente sea más razonable ordenar las matrices de estructuras por índices (me refiero a reordenar los índices, no las estructuras en sí), pero depende del tamaño de la estructura, claro.

 
Alexey Navoykov:

He resaltado en amarillo lo que faltaba.

Gracias, me lo perdí.

Creo que es mejor empezar por Inicio y luego por Contar en orden de argumentos.

La señal se toma prestada de MT4-ArraySort.

Por cierto, probablemente sería más razonable ordenar las matrices de estructuras por índices (me refiero a reordenar los índices, no las estructuras en sí).

Esto fue lo primero que se me ocurrió, pero lo dejé. Porque requiere usar ArrayCopy del array inicial y del array de índices. Y esto es una memoria adicional. Y la máquina no puede permitirse esa ordenación de una matriz, por ejemplo, de millones de elementos MqlTick.

Podríamos haber incluido dos variantes de ordenación, pero no lo he hecho en el código fuente. En la demostración, tal vez, lo más valioso sea la usabilidad y el método de aplicación. Después de estudiarlo, ya está claro cómo añadir a sus necesidades y hacer un análogo para otras funciones de arrays con estructuras (ArrayMaximum, etc.).

ArraySort - Операции с массивами - Справочник MQL4
ArraySort - Операции с массивами - Справочник MQL4
  • docs.mql4.com
//| Script program start function                                    |
 
fxsaber:
Ordenación práctica de un conjunto de estructuras


Aplicación


Resultado

¿Cómo convertir este código en una clase simple sin usar #define?

 
Vladimir Pastushak:

¿Cómo convertir este código en una clase simple sin usar #define?

No se puede. Se supone que ArraySortStruct se utiliza como una función sin entrar en cómo se organiza.

Sólo hay que poner en enludnik su código fuente y olvidarse de él. Después de eso, una "función" realmente útil para cualquier principiante (y no sólo) está siempre a mano.

 
Amigos, tirar en una referencia si hay tal, necesita la bandera de la hora de apertura de la tarde (adicional) la sesión de negociación en FORTS MOEX, y como todos miraron a través, pero no encontró, no quiero escribir una definición muleta a las 19:00 o 19:05 se abrirá la sesión de negociación
 

Un número aleatorio de 0 a máximo con igual probabilidad:

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:

El multi-buffer es genial para acelerar el editor y es seguro.

No escribe nada en el disco y sólo mantiene los datos en la memoria.

¿A partir de qué puntuación podré insertar una imagen en el sitio web?
 
Vict:

Un número aleatorio de 0 a máximo con igual probabilidad:

Su función es 100% equivalente:

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

porque, en primer lugar.

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

se simplifica a

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

por lo tanto, en segundo lugar

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

se realiza siempre una vez.

La complejidad es una declaración detallada de la simplicidad. ))

 
Nikolai Semko:

Su función es 100% equivalente:

porque, en primer lugar.

se simplifica a

por lo tanto, en segundo lugar

se realiza siempre una vez.

La complejidad es una declaración detallada de la simplicidad. ))

Es usted muy considerado, gracias. Me equivoqué, no puse paréntesis, así que usaría la función "injusta".

SZZ: se han hecho correcciones en el post original.