Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 134

 
Facile ordinamento di una serie di strutture
#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);                                                             \
}


Applicazione

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


Risultato

Бары без сортировки - как получили.
                 [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:
Ordinamento pratico di una serie di strutture


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

Il giallo ha evidenziato le cose mancanti, e mi sembra che sia meglio in ordine di argomenti, prima Start e poi Count.

A proposito, è probabilmente più razionale ordinare gli array di strutture per indici (intendo riordinare gli indici, non le strutture stesse), ma dipende dalla dimensione della struttura, ovviamente.

 
Alexey Navoykov:

Ho evidenziato in giallo ciò che mancava.

Grazie, mi era sfuggito.

Penso che sia meglio iniziare con Start e poi Count in ordine di argomenti.

Il segnale è preso in prestito da MT4-ArraySort.

A proposito, sarebbe probabilmente più ragionevole ordinare gli array di strutture per indici (intendo riordinare gli indici, non le strutture stesse).

Questa è stata la prima cosa che mi è venuta in mente, ma ci ho rinunciato. Perché richiede l'uso di ArrayCopy dell'array iniziale e dell'array di indici. E questa è una memoria aggiuntiva. E la macchina non può permettersi un tale ordinamento di un array, per esempio, di milioni di elementi MqlTick.

Avremmo potuto includere due varianti di ordinamento, ma non l'ho fatto nel codice sorgente. Nella dimostrazione, forse, la cosa più preziosa è l'usabilità e il metodo di implementazione. Dopo averlo studiato, è già chiaro come aggiungere alle vostre necessità e fare un analogo per altre funzioni di array con strutture (ArrayMaximum, ecc.).

ArraySort - Операции с массивами - Справочник MQL4
ArraySort - Операции с массивами - Справочник MQL4
  • docs.mql4.com
//| Script program start function                                    |
 
fxsaber:
Ordinamento pratico di una serie di strutture


Applicazione


Risultato

Come convertire questo codice in una classe semplice senza usare #define ?

 
Vladimir Pastushak:

Come convertire questo codice in una classe semplice senza usare #define ?

Non si può. ArraySortStruct dovrebbe essere usato come una funzione senza entrare nel modo in cui è organizzato.

Basta buttare dentro qualche enludnik il suo codice sorgente e dimenticarsene. Dopo di che una "funzione" davvero comoda per qualsiasi principiante (e non solo) è sempre a portata di mano.

 
Gente, gettare in un riferimento se c'è tale, bisogno della bandiera di tempo di apertura della sera (supplementare) sessione di trading su FORTS MOEX, e come tutti guardato attraverso ma non ha trovato, non voglio scrivere una definizione stampella alle 19:00 o 19:05 si apre sessione di trading
 

Un numero casuale da 0 a max con uguale probabilità:

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:

Il multi-buffer è ottimo per velocizzare l'editor ed è sicuro.

Non scrive nulla sul disco e mantiene solo i dati in memoria.

a quale rating potrò inserire un'immagine sul sito web?
 
Vict:

Un numero casuale da 0 a max con uguale probabilità:

La vostra funzione è equivalente al 100%:

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

perché, in primo luogo.

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

semplifica a

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

quindi, in secondo luogo

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

viene sempre eseguito una volta.

La complessità è una dichiarazione dettagliata della semplicità. ))

 
Nikolai Semko:

La vostra funzione è equivalente al 100%:

perché, in primo luogo.

semplifica a

quindi, in secondo luogo

viene sempre eseguito una volta.

La complessità è una dichiarazione dettagliata della semplicità. ))

Siete molto premurosi, grazie. Ho fatto un errore, non ho messo le parentesi, quindi userei la funzione "sleale".

SZZ: apportate correzioni al post originale.

Motivazione: