mql5言語の特徴、微妙なニュアンスとテクニック - ページ 134

 
構造体配列の 容易なソート
#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);                                                             \
}


アプリケーション

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


結果

Бары без сортировки - как получили.
                 [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:
構造体の配列を簡便にソート する


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

黄色は足りないものを強調したもので、議論の順番としてはStart、Countの順が良いように思います。

ちなみに、構造体の配列をインデックスでソートする(構造体そのものではなくインデックスを並べ替えるという意味です)方が合理的かもしれませんが、もちろん構造体のサイズによります。

 
Alexey Navoykov:

足りないものを黄色で強調しました。

ありがとうございます、見逃してました。

Startから始めて、Countの順に論証していくのが良いと思います。

シグナルはMT4-ArraySortから 拝借しています。

ちなみに、構造体の配列はインデックスでソートする方が合理的でしょう(構造体そのものではなく、インデックスを並べ替えるという意味です)。

これが一番最初に思い浮かんだのですが、断念しました。なぜなら、初期配列とインデックスの配列のArrayCopyを使う必要があるからです。そして、これが追加メモリーです。そして、例えば数百万個のMqlTick-elementの配列に対して、このようなソートをする余裕は機械にはない。

2つのソートバリアントを入れることもできたのですが、ソースコードではやっていないんです。デモでは、おそらく最も価値があるのは、使い勝手と実装の方法です。これを勉強した後、あなたのニーズに合わせて、構造体を持つ配列の他の関数(ArrayMaximumなど)のアナログを作る方法は既に明らかです。

ArraySort - Операции с массивами - Справочник MQL4
ArraySort - Операции с массивами - Справочник MQL4
  • docs.mql4.com
//| Script program start function                                    |
 
fxsaber:
構造体の配列を簡便にソート する


アプリケーション


結果

このコードを#defineを使わずにシンプルなクラスに変換するには?

 
Vladimir Pastushak:

このコードを#defineを使わずにシンプルなクラスに変換するには?

無理でしょう。ArraySortStructは、どのように構成されているかには触れずに、関数として使用 することを想定しています。

ただ、そのソースコードをエンルードニクに投げて、忘れてください。その後、初心者にとって本当に便利な(そしてそれだけではない)「機能」が常に手元にあるのです。

 
そのようなものがある場合は、参照に投げる、フォルツMOEXで夕方(追加)取引セッションの 開始の時間のフラグを必要とし、すべてのように、を介して見たが見つかりませんでした、19:00または19:05で松葉杖の定義を記述することは望んでいない取引セッションをオープンする予定です
 

0からmaxまでの乱数を等確率で指定する。

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:

マルチバッファはエディタのスピードアップに最適で、安全です。

ディスクには何も書き込まず、メモリにのみデータを保持します。

Webサイトに画像を挿入できるようになるのは、どの程度のレーティングからですか?
 
Vict:

0からmaxまでの乱数を等確率で指定する。

あなたの機能は100%同等です。

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

というのも、まず第一に

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

というのは

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

従って、次に

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

は必ず1回実行されます。

複雑さとは、単純さを細かく表現したものです。))

 
Nikolai Semko:

あなたの機能は100%同等です。

というのも、まず第一に

というのは

従って、次に

は必ず1回実行されます。

複雑さとは、単純さを細かく表現したものです。))

思いやりがあるんですね、ありがとうございます。間違えて、括弧を付けなかったので、"unfair "機能を使用します。

SZZ:元の投稿に修正を加えました。