エキスパート: トレーダーのためのMQL5プログラミング - 書籍からのソースコード。第6部 - ページ 2

 
Stanislav Korotky #:
注文、取引、ポジションはいずれにせよ時間枠とは関係ありません。何か誤解しているか、表現が間違っている。
すみません、私の言葉の選択が紛らわしかったのだと思います 例えば、2025-10-01 00:00:00から2025-10-22 23:59:59までの取引のように、指定した日付範囲内で取引された取引/注文を選択したいとします。
 
pauldic #:
申し訳ありませんが、私の言葉の選択が紛らわしかったようで、「タイムフレーム」とは「日付範囲」のことです。例えば、2025-10-01 00:00:00から2025-10-22 23:59:59までの案件のように、指定した日付範囲内で取引された案件/注文を選択したいとします。

取引履歴のサブレンジを分析したい場合、フィルタリングの前に、フィルタリングのコード自体に影響を与えることなく、履歴のこの部分のみを要求する方が効率的です:

input datetime SubrangeFrom = 0;
input datetime SubrangeTo = 0;

...

{
   HistorySelect(SubrangeFrom, SubrangeTo);
   // ... フィルターのコードはそのままここに置く
}

何らかの理由で、HistorySelect で適用したグローバルな範囲内の(より狭い)サブ範囲を選択したい場合、フィルタリング・コード内でこのようにできます:

{
      // これらの一部はこちら

      // HistorySelect(0, LONG_MAX);
      // HistorySelectByPosition(PositionID);
      ...
      DealTuple deals[];
      if(SubrangeFrom != SubrangeTo && SubrangeFrom < SubrangeTo)
      {
         filter.let(DEAL_TIME, SubrangeFrom - 1, IS::GREATER).let(DEAL_TIME, SubrangeTo + 1, IS::LESS);
      }
      filter.let(DEAL_POSITION_ID, PositionID).select(deals, true);
      ...
}

ハイライトされた黄色の行では、追加の修飾子 IS::GREATER と IS::LESS を使用して、日付の範囲 [SubrangeFrom, SubrangeTo] に対して 2 つの条件を設定しています (デフォルトでは、これらはlet() の他のコールでは指定されず、IS::EQUAL が単一の値フィールドに対して通常使用されます)。

なぜなら、HistorySelect は注文の別の日時プロパティ、すなわち注文の実行時間 (ORDER_TIME_DONE) に適用されるからです。また、有効な注文が多数ある場合、(履歴にない)有効な注文のサブレンジをフィルタリングするのも面白いかもしれません。

MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5の サンプルスクリプトを参考にしてください。
 
Stanislav Korotky #:

取引履歴のサブレンジを分析したい場合、フィルタリングの前に、フィルタリングのコード自体に影響を与えることなく、履歴のこの部分のみを要求する方が効率的です:

何らかの理由で、HistorySelect で適用したグローバルレンジの中の(より狭い)サブレンジを選択したい場合、フィルタリングのコードでこのようにすることができます:

黄色でハイライトされた行は、追加の修飾子 IS::GREATER と IS::LESS を使用して、datetime の範囲 [SubrangeFrom, SubrangeTo] に対して 2 つの条件を設定します (デフォルトでは、これらはlet() の他のコールでは指定されず、IS::EQUAL が単一の値フィールドに対して通常使用されます)。

なぜなら、HistorySelect は注文の別の日時プロパティ、すなわち注文の実行時間 (ORDER_TIME_DONE) に適用されるからです。また、有効な注文が多数ある場合、(履歴にない)有効な注文のサブレンジをフィルタリングするのも面白いかもしれません。

MQL5/Scripts/MQL5Book/p6/TradeHistoryPrint.mq5の サンプルスクリプトを参考にしてください。
StanislavKorotky ありがとうございます。このスクリプトは私にとって素晴らしい出発点です。
 

MQL5/Include/MQL5Book/TradeUtils.mqhの バグ修正。

   bool Equal(const double v1, const double v2)
   {
      return v1 == v2 || fabs(v1 - v2) < DBL_EPSILON * fmax(1.0, fmax(fabs(v1), fabs(v2)));
   }
ファイル:
TradeUtils.mqh  12 kb
 
pauldic #:

コードを挿入する 際は CODEボタン(Alt-S)を使用して ください。

モデレーターが誤って貼り付けられたコードを整形しました。通常、そのようなコードは削除されます。

StanislavKorotky このエラーを調べるのを手伝ってくれませんか。私は、コードが修正なしで前の月に動作することを知っていたので、MT5のアップデート後に始まったと思います。

parameter convertion type 'long[][2]' to 'string[][] &' is not allowed SymbolFilter.mqh 199 20

parameter convertion type 'double[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 332 20
parameter convertion type 'long[][2]' to 'string[][] &' is not allowed TradeFilter.mqh 163 17


以下のコードが問題の再現に役立つと思われる:


ポール・ディックさん、こんにちは。

https://www.mql5.com/ja/code/57233、配列をソートしてみてください。

Introsort (Introspective sort) using Function Pointers
Introsort (Introspective sort) using Function Pointers
  • 2025.03.18
  • www.mql5.com
A hybrid sorting algorithm that provide fast performance for sorting arrays of simple types, structures or object pointers.
 

R2-RSquared.mqhに 基づくカスタム最適化 基準の計算ファイルの更新版を添付します。この中で、可変ロットの場合の計算が修正されています。

最適化結果の 表から判断して、回収率とシャープパラメータの組み合わせが得られています。

使用例

double OnTester()
{
   HistorySelect(0, LONG_MAX);
   
   #define  STAT_PROPS 5
   
   const ENUM_DEAL_PROPERTY_DOUBLE props[STAT_PROPS] =
   {
      DEAL_PROFIT, DEAL_SWAP, DEAL_COMMISSION, DEAL_FEE, DEAL_VOLUME
   };
   double expenses[][STAT_PROPS];
   ulong tickets[]; // ここでは'select'プロトタイプにマッチさせるためだけに使用するが、デバッグには便利である。
   
   DealFilter filter;
   filter.let(DEAL_TYPE, (1 << DEAL_TYPE_BUY) | (1 << DEAL_TYPE_SELL), IS::OR_BITWISE)
      .let(DEAL_ENTRY, (1 << DEAL_ENTRY_OUT) | (1 << DEAL_ENTRY_INOUT) | (1 << DEAL_ENTRY_OUT_BY), IS::OR_BITWISE)
      .select(props, tickets, expenses);

   const int n = ArraySize(tickets);
   
   double balance[];
   double volumes[]; // R2 基準を使用する場合は、取引量を考慮する。
   
   ArrayResize(balance, n + 1);
   balance[0] = 0;
   ArrayResize(volumes, n + 1);
   volumes[0] = 0;
   
   for(int i = 0; i < n; ++i)
   {
      double result = 0;
      for(int j = 0; j < STAT_PROPS - 1; ++j)
      {
         result += expenses[i][j];
      }
      // より多くの投資により、より多くのリターンが期待できる。
      volumes[i + 1] = expenses[i][STAT_PROPS - 1] + volumes[i];
      balance[i + 1] = result + balance[i];
   }
   
   const double r2 = RSquaredTest(balance, volumes);
   
   #undef  STAT_PROPS
   
   return r2 * 100;
}
ファイル:
RSquared.mqh  4 kb
 

最近Frameを勉強していて、あなたのコード、FrameTransfer.mq5をテストしました。この行は現在のMT5コンパイラでエラーを投げています。確認してください:#property tester_set "FrameTransfer.set" (テスターセットのファイル拡張子が無効です。'*.set' expected FrameTransfer.mq5)

コンパイルに成功するには、このように変更する必要があります:#property tester_set "⦅Presets⦆⦆FrameTransfer.set"

これでは、##property tester_set "/Presets/FrameTransfer.set"`でも失敗してしまいます。

おそらくアルゴリズムブックの記述を修正できるだろう:


 
hini #property tester_set "FrameTransfer.set" (テスターセットファイルの拡張子が無効です。'*.set'が期待されるFrameTransfer.mq5です)

コンパイルを成功させるには、以下のように変更する必要があります:#property tester_set "¦Presets¦FrameTransfer.set"

と設定しても失敗する。

おそらく、アルゴリズムブックの記述を変更できるだろう:


これは明らかなコンパイラのバグで、コードに "invalid tester set file extension, '*.set' expected "というエラーを与えます:

#property tester_set "FrameTransfer.set"

これは明らかなコンパイラのバグです。ファイルの場所のパスは関係ありません。

このバグは、少なくとも2024年以来、長い間存在している。なぜMQがそれを修正しようとしないのか、私にはわからない。

本の編集に関しては、今回は必要ないが、いずれにせよ、本は現在完全にMQの管理下にある。

 
Stanislav Korotky 管理 下にある。
確認し、報告した。修正されるかどうか見てみよう。
 
Stanislav Korotky #:

これは明らかなコンパイラのバグである:「無効なテスター・セット・ファイルの拡張子、'*.set'が期待されています:



MetaEditorのバージョンを維持するには、ファイル名の最後にゼロを追加してください:"myset.set0"