Features of the mql5 language, subtleties and tricks - page 296

 
Also encoding invalid string values is not allowed: StringToTime("1968.10.09") returns -1

 

By the way, if someone is interested in programming dates, we could write a mini-library for working with dates before 1970. There was some life there)).

For programming tasks not related to market/forex.

 
On Windows, the FILETIME type stores time as a count of 100-nanosecond intervals that have elapsed since 0:00 GMT on 1 January 1601. But, then you have to use Windows API functions, instead and then it is also not possible to import these old dates into custom symbols.
 
Maxim Kuznetsov #:

Who knows how to make this work ?

to get a Sort template ( array_pointers, compare_function )

While using a sort function that accepts a function pointer to compare function is the standard approach for sorting array structures or object pointers, there is a much simpler technique "Operator overloading" that works with a plain sort function without the need for writing a separate compare function.

Sorting array of structures by operator overloading:

//+------------------------------------------------------------------+
//| Templated class                                                  |
//+------------------------------------------------------------------+
template <typename T>
class Foo
  {
public:
                     Foo(void) { payload=(T)10*MathRand()/MathRand(); }
                    ~Foo(void) {   }
public:
   T                 payload;

public:
   //--- operator overloading for sorting
   bool              operator < (Foo<T> &other)   { return this.payload < other.payload; }
  };

//--------------------------------------------------------------------------------------------
// TEMPLATE SORTING
// function is templated for any type of array (e.g., int[], double[], pointers to objects[]).
//--------------------------------------------------------------------------------------------
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];   // array of object pointers

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

Also for sorting array of structures, we add an overloaded operator:

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

   //--- operator overloading for sorting
   bool              operator < (MyStruct &other)   { return this.A < other.A; }
  };

This allows to simply sort like: Sort(structArray);

 
amrali #:

We also add an overloaded operator to sort arrays of structures:

This allows simple sorting like: Sort(structArray);

It is often necessary to sort such an array by different fields.


There seem to be many implementations of such sorting in this thread. When the user has almost nothing to write.

 
fxsaber #:

It is often necessary to sort such an array by different fields.


I think there were many implementations of such sorting in this thread. When the user doesn't need to write almost anything.

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

user-user:

INC_SORT_BY(array,field) - sort an array of structures by a given field;

Shorter is hardly possible anymore :-)

 

Forum on trading, automated trading systems and testing trading strategies

Features of mql5 language, subtleties and techniques of work

Maxim Kuznetsov, 2025.03.21 09:30 AM

/// 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);
}
I recommend ArrayPrint for an array of structures.
 

Forum on trading, automated trading systems and testing trading strategies

Features of mql5 language, subtleties and techniques of work

Maxim Kuznetsov, 2025.03.21 09:30

// tpl. 3-way compare func.
template <typename T>
int Great(T &one,T & two) {
   return (int)(two-one);
}
Should be double.
 

Forum on trading, automated trading systems and testing trading strategies

Features of mql5 language, subtleties and techniques of work

Maxim Kuznetsov, 2025.03.21 09:30 AM

// 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)
I think you can do without do-while - only curly brackets.
 

it's all handwritten :-)

my computer died at the weekend, now I'm doing it all over again and I haven't managed to get the sources from the backups yet

in the given code except that names do not like...a little differently it is necessary to name.

PS/ there are still problems with Print() and templates/arrays in MQL. The built-in Print does not work like all the others

PPS/ ArrayPrint is inconvenient because it prints the whole array (they can be of epic size). You still have to redefine it, reducing the output