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

 
fxsaber #:

機能性(サブフィールドやメソッド)と使い勝手をどう維持するのかがわからない。このオプションは、あなたのニーズに合っているかもしれません。


アプリケーションです。

とても早くて、今は問題なく使えています!ありがとうございました。


ロシアに愛をこめて❤️!;-)

 
昔々、MQL5でこのようなマクロを書くのは簡単でした。
class MqlRatestime
{
public:
  static void f( MqlRates &Value ) { Print(Value.time); }
};

class MqlTicktime
{
public:
  static void f( MqlTick &Value ) { Print(Value.time); }
};

void OnStart()
{  
  MqlRates Rates;
  MqlTick Tick;
  
  MACROS(Rates, time); // MqlRatestime::f(Rates);
  MACROS(Tick, time);  // MqlTicktime::f(Tick);
}


現在のMQL5では可能でしょうか?この壁を乗り越えるための工夫が足りなかったのです。

template declarations are allowed on global, namespace or class scope only
 
fxsaber #:
昔々、MQL5でこのようなマクロを書くのは簡単でした。


現在のMQL5では可能でしょうか?この障害を克服するための臨機応変な対応ができていないのです。

MqlRatestクラス(のテンプレート)をマクロ置換の中で宣言する必要があるのでしょうか?
 
mktr8591 #:
MqlRatestクラス(のテンプレート)をマクロ置換の中で宣言する必要があるのですか?
パラメータの種類によって、マクロの代入を変える必要があるようです。
ただ、なぜ関数のオーバーロードではなく、マクロの代入で行うのかが理解できない。
 
mktr8591 #:
MqlRatestクラス(そのテンプレート)をマクロ置換の内部で宣言する必要があるのですか?

いいえ、クラスはすでに宣言されています。コメントには、どのような結果を得たいかを指定します。マクロへの入力はオブジェクトで、出力はそのオブジェクトの型名を含むクラスである。

 
Sergey Gridnev #:
パラメータの種類によって、マクロの代入を変える必要があるようです。
ただ、なぜ関数のオーバーロードではなく、マクロの代入で行う必要があるのかが理解できない。

今回のタスクは、この 中から生まれたものです。

トレーディング、自動売買システム、ストラテジーテストに関するフォーラム

mql5の特性、ヒントとコツ

fxsaber, 2022.02.11 15:44

ArraySortStruct_Define(MqlRates, open)
ArraySortStruct_Define(MqlRates, high)
ArraySortStruct_Define(MqlRates, time)

void OnStart()
{
  MqlRates Rates[];
  
  CopyRates(_Symbol, PERIOD_CURRENT, 0, 5, Rates); // Взяли бары
  
  Print("\nБары без сортировки - как получили.");
  ArrayPrint(Rates);
  
  Print("\nСортируем по open-цене.");
  ArraySortStruct(MqlRates, Rates, open);
  ArrayPrint(Rates);

  Print("\nСортируем по high-цене.");
  ArraySortStruct(MqlRates, Rates, high);
  ArrayPrint(Rates);

  Print("\nСортируем по времени.");
  ArraySortStruct(MqlRates, Rates, time);
  ArrayPrint(Rates);
}

入力パラメータに色をつけ、その中に型を指定するようにしました。このマクロでは、3つの入力パラメータを得ることができます。そして、2つ欲しいですね。タイプなしで。

 
fxsaber #:

いいえ、クラスはすでに宣言されています。コメントには、どのような結果を得たいかを指定します。マクロへの入力はオブジェクトで、出力はそのオブジェクトの型名を含むクラスである。

この問題を解決する方法がわからない。

そして、2つのパラメータを持つArraySortStructへ - これがその仕組みです。

#define  ArraySortStruct(ARRAY, FIELD) SortOnField_##FIELD::SORT::Sort(ARRAY)

 ArraySortStruct_Define(SortOnField_, open)
ArraySortStruct_Define(SortOnField_, high)
ArraySortStruct_Define(SortOnField_, time)


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);
  }
 
mktr8591 #:

そして、2つのパラメータを持つArraySortStructへ-というわけです。

その通りです!ありがとうございました。平らなところでやりすぎてしまった。整理のために、あなたのバリアントを残しておきます。

// Сортировка массива структур и указателей на объекты по полю.
#define  ArraySortStruct_Define(FIELD)                                            \
namespace SortOnField_##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;                                                                    \
    }                                                                            \
  };                                                                             \
}

#define  ArraySortStruct(ARRAY, FIELD) SortOnField_##FIELD::SORT::Sort(ARRAY)


アプリケーションです。

ArraySortStruct_Define(open)
ArraySortStruct_Define(high)
ArraySortStruct_Define(time)

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


ZZY サブフィールドやメソッド別では、うまくいかないのが残念です。

 
これは誰にとってもニュースではないかもしれませんが、私にとっては予想外のことです。
DLL を異なる MT5 プログラムで同時に使用する場合、
それを使用する最初に実行するプログラムによって一度だけロードされることを念頭に置いてください。
つまり、DLL環境は何度インポートしても 1つの共通プロセスになっています。
キャッチは?DLLで使用されるグローバルポインタは、すべて同じ共有プロセス空間にあります。
そして、これがとても便利なんです。
 
Roman #:
もしかしたら、これは誰にとってもニュースではないのかもしれませんが、私にとっては予想外のことでした。DLLを異なるプログラムMT5, で同時に使用する場合、最初に使用するプログラムによって一度だけロードされることに留意してください。つまり、DLLの状態は、何度


インポートしても、共通の1つのプロセスにあるのです。キャッチは?DLLで使用されるグローバルポインタは、すべて同じ共有プロセス空間にあります。そして、これがとても便利なんです。

これは何も新しいことではなく、生まれたときからずっとそうなのです。

データが __atomic__ より大きい場合のみ、クリティカルセクションでラップ/プロテクトしてアクセスする必要がある (または、端末 std::thread への mutex が必要)。

理由: