Особенности языка mql5, тонкости и приёмы работы - страница 294

 
Также не допускается кодирование недопустимых строковых значений: StringToTime("1968.10.09") возвращает -1

 

Кстати, если кому-то интересно программировать даты, могли бы написать мини-библиотеку для работы с датами до 1970г. Там же была какая-то жизнь ))

Для программирования задач, не связанных с рынком/форексом.

 
В Windows тип FILETIME хранит время как счетчик 100-наносекундных интервалов, прошедших с 0:00 по Гринвичу 1 января 1601 года. Но тогда вам придется использовать функции Windows API, и тогда также невозможно будет импортировать эти старые даты впользовательские символы.
 
Maxim Kuznetsov #:

Кто знает, как заставить это работать?

получить шаблон Sort ( array_pointers, compare_function )

Хотя использование функции сортировки, принимающей указатель на функцию сравнения, является стандартным подходом для сортировки структур массивов или указателей объектов, существует гораздо более простая техника "Перегрузка операторов", которая работает с простой функцией сортировки без необходимости написания отдельной функции сравнения.

Сортировка массива структур с помощью перегрузки операторов:

//+------------------------------------------------------------------+
//| Шаблонный класс|
//+------------------------------------------------------------------+
template <typename T>
class Foo
  {
public:
                     Foo(void) { payload=(T)10*MathRand()/MathRand(); }
                    ~Foo(void) {   }
public:
   T                 payload;

public:
   //--- перегрузка операторов для сортировки
   bool              operator < (Foo<T> &other)   { return this.payload < other.payload; }
  };

//--------------------------------------------------------------------------------------------
// СОРТИРОВКА ШАБЛОНОВ
// Функция шаблонизируется для любого типа массива (например, int[], double[], указатели на объекты[]).
//--------------------------------------------------------------------------------------------
template <typename T>
void Sort(T &a[])
{
   for(int i=1; i < ArraySize(a); ++i)
      for(int j=i; j>0 && (a[j] < a[j-1]); j--)
      {
         T tmp=a[j]; a[j]=a[j-1]; a[j-1]=tmp;
      }
}

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
void OnStart()
{
   Foo<int> *ptrArray[7];   // массив указателей объектов

   for(int i=0;i<7;i++) {
      ptrArray[i]=new Foo<int>();
   }

   Sort(ptrArray);

   for(int i=0;i<7;i++) {
      printf("%d. payload=%s",i,(string)ptrArray[i].payload);
      delete ptrArray[i];
   }
}

Также для сортировки массивов структур мы добавляем перегруженный оператор:

//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
struct MyStruct
  {
   int               A;
   int               B;
   int               C;

   //--- перегрузка операторов для сортировки
   bool              operator < (MyStruct &other)   { return this.A < other.A; }
  };

Это позволяет просто сортировать, как: Sort(structArray);

 
amrali #:

Также для сортировки массивов структур мы добавляем перегруженный оператор:

Это позволяет просто сортировать, как: Sort(structArray);

Часто требуется сортировать такой массив по разным полям.


Вроде, в этой ветке было много реализаций таких сортировок. Когда пользователю почти ничего не нужно писать.

 
fxsaber #:

Часто требуется сортировать такой массив по разным полям.


Вроде, в этой ветке было много реализаций таких сортировок. Когда пользователю почти ничего не нужно писать.

/// PRINT`s
template <typename T>
void xPrint(T &arr[]) 
{
   int total=ArraySize(arr);
   for(int i=0;i<total;i++)
      ::Print(ToString(arr[i]));
}
template <typename T>
void xPrint(T &value) 
{
   ::Print(value);
}
#define Print xPrint

/// SORTING

template <typename T>
void Swap(T &one,T &two) 
{
   T tmp=two;
   two=one;
   one=tmp;
}
// tpl. 3-way compare func.
template <typename T>
int Great(T &one,T & two) {
   return (int)(two-one);
}
// Sort with 3-way cmp.function
#define SORT(arr,great) do { \
   int total=ArraySize(arr);  \
   for(int i=1;i<total;i++) for(int j=0;j<i;j++) { \
      if (great(arr[i],arr[j])>0) Swap(arr[i],arr[j]); \
   }  \
} while(0)
// Sort by field
#define SORT_BY(arr,field,great) do { \
   int total=ArraySize(arr);  \
   for(int i=1;i<total;i++) for(int j=0;j<i;j++) { \
      if (great(arr[i].##field,arr[j].##field)>0) Swap(arr[i],arr[j]); \
   }  \
} while(0)
// Sort in inc.order (ascending)
#define INC_SORT(arr) SORT(arr,Great)
// Sort by field
#define INC_SORT_BY(arr,field) SORT_BY(arr,field,Great)


////////////////////////////
// TEST
struct rFoo {
   int key;
   double value;
}; 
int Great(rFoo &one,rFoo &two) {
   return two.key-one.key;
}
string ToString(const rFoo &r) {
   return StringFormat(".key=%d value=%.f",r.key,r.value);
}
rFoo mass[] = {
   {11,0.18},
   {7,7.81},
   {8,0.1},
   {100,5.11},
   {0,3.29}
};


void OnStart()
{
   INC_SORT(mass); 
   Print(mass);
   INC_SORT_BY(mass,value); 
   Print(mass);
}

пользователю-пользователево:

INC_SORT_BY(array,field) - сортировать массив структур по заданному полю; 

Короче уже вряд-ли возможно :-)

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Особенности языка mql5, тонкости и приёмы работы

Maxim Kuznetsov, 2025.03.21 09:30

/// PRINT`s
template <typename T>
void xPrint(T &arr[]) 
{
   int total=ArraySize(arr);
   for(int i=0;i<total;i++)
      ::Print(ToString(arr[i]));
}

string ToString(const rFoo &r) {
   return StringFormat(".key=%d value=%.f",r.key,r.value);
}
Рекомендую ArrayPrint для массива структур.
 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Особенности языка mql5, тонкости и приёмы работы

Maxim Kuznetsov, 2025.03.21 09:30

// Sort by field
#define SORT_BY(arr,field,great) do { \
   int total=ArraySize(arr);  \
   for(int i=1;i<total;i++) for(int j=0;j<i;j++) { \
      if (great(arr[i].##field,arr[j].##field)>0) Swap(arr[i],arr[j]); \
   }  \
} while(0)
Вроде, можно без do-while - только фигурные скобки.
 

это всё "навсидку, с руки" написано :-)

у меня на выходных комп сдох, сейчас всё по новой и до достать исходники из бекапов руки ещё не дошли

в приведённом коде разве что имена ненравятся..чуть иначе надо именовать

PS/ с Print() и шаблонами/массивами в MQL ещё есть проблемы. Встроенный Print не как все прочие работает

PPS/ ArrayPrint неудобен тем что печатает весь массив (они бывают эпичных размеров). Всё равно приходится переопределять, сокращая выхлоп