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; 

黄色强调了所缺的东西,在我看来,最好是按照先开始、后计数的参数顺序来排序。

顺便说一下,按索引对结构数组进行排序可能更合理(我指的是重新排列索引,而不是结构本身),但这当然取决于结构的大小。

 
Alexey Navoykov:

我用黄色强调了所缺少的东西。

谢谢,我错过了。

我认为按论证顺序从 "开始 "开始,然后是 "计数",这样比较好。

该信号借用了MT4-ArraySort

顺便说一下,按索引对结构数组进行排序可能更合理(我是指重新排列索引,而不是结构本身)。

这是第一个想到的东西,但我放弃了。因为它需要使用初始数组和索引数组的ArrayCopy。而这是额外的记忆。而机器无法承担这样的排序,例如,数百万个MqlTick-elements的阵列。

我们本可以包括两种排序变体,但我在源代码中没有这样做。在演示中,也许,最有价值的是可用性和实施方法。在研究了它之后,已经很清楚如何根据你的需要来增加,并为其他带有结构的数组函数(ArrayMaximum,等等)做一个类似物。

ArraySort - Операции с массивами - Справочник MQL4
ArraySort - Операции с массивами - Справочник MQL4
  • docs.mql4.com
//| Script program start function                                    |
 
fxsaber:
便于对数组 结构进行排序


应用


结果

如何在不使用#define的情况下将这段代码转换为一个简单的类 ?

 
Vladimir Pastushak:

如何在不使用#define的情况下将这段代码转换为一个简单的类 ?

你不能。ArraySortStruct 应该是作为一个函数来使用 的,而没有涉及到它是如何组织的。

只要把一些 enludnik 其源代码扔进去就可以了。之后,对于任何初学者来说,一个真正方便的(不仅是)"功能 "总是唾手可得。

 
伙计们,如果有这样的参考,需要在FORTS MOEX的晚间(额外的交易时段)开盘时间的标志,像所有通过寻找但没有找到,不想写一个拐杖定义在19:00或19:05将打开交易时段。
 

一个从0到最大的随机数,概率相等。

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:

多缓冲区对于加快编辑器的速度很有帮助,而且很安全。

它不向磁盘写任何东西,只在内存中保留数据。

我在什么等级的网站上可以插入图片?
 
Vict:

一个从0到最大的随机数,概率相等。

你的功能是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);

始终执行一次。

复杂性是对简单性的详细说明。))

 
Nikolai Semko:

你的功能是100%的等同。

因为,首先。

简化为

因此,其次

始终执行一次。

复杂性是对简单性的详细说明。))

你考虑得很周到,谢谢你。我犯了一个错误,没有放括号,所以我会用 "不公平 "功能。

SZZ:对原帖进行了更正。