【MQL5】HistorySelect関数の使い方と自動売買実装コード

1. HistorySelect関数の概要と実務での活用法

MQL5におけるHistorySelectは、取引口座の「過去の注文履歴や約定履歴」を端末のメモリ上に読み込むための関数です。MT4から移行した開発者が最初につまずくポイントの一つが、この「履歴の参照方法」の違いです。

MT4では、単に OrderSelect を使えば過去の注文にアクセスできましたが、MQL5では「まず HistorySelect で特定の期間を指定して履歴をキャッシュ(一時保存)し、その中から個別のデータを抽出する」という2ステップのプロセスが必要になります。

実務においては、以下のような場面で必須となります。
– 当日の合計損益を計算してリミッターをかける(デイリー利益目標の達成確認)
– 直前のトレードが「勝ち」だったか「負け」だったか判定し、次のロット数を変更する(マーチンゲールや資金管理)
– EAが異常終了した際、直前のポジションがどう処理されたかを履歴から復元する

この関数を呼び出さない限り、HistoryDealsTotal() などの履歴関連関数はすべて「0」を返してしまうため、ロジックを組む上での「入り口」となる極めて重要な関数です。

2. 構文と戻り値

HistorySelect 関数の基本的な構文は以下の通りです。

bool HistorySelect(
   datetime  from_date,   // 開始日時
   datetime  to_date      // 終了日時
);

パラメーター

  • from_date: 履歴を取得したい期間の開始時間を指定します。
  • to_date: 履歴を取得したい期間の終了時間を指定します。

戻り値

  • true: 履歴の取得に成功した場合。
  • false: 失敗した場合。

実務上のテクニックとして、現在までの全履歴を取得したい場合は、to_dateTimeCurrent()(サーバーの現在時刻)を指定し、from_date には 0 または十分古い日付を指定します。

3. 具体的な使い方・実践サンプルコード

以下は、EA内で「本日(0時0分以降)の確定損益」を合算して出力する実用的なコード例です。

void OnTick()
{
   // 本日の0時0分を取得
   datetime today_start = iTime(_Symbol, PERIOD_D1, 0);
   // 現在時刻を取得
   datetime now = TimeCurrent();

   // 1. まずHistorySelectで本日の履歴をメモリに読み込む
   if(HistorySelect(today_start, now))
   {
      // 2. 履歴内の「約定(Deal)」の総数を取得
      int total_deals = HistoryDealsTotal();
      double total_profit = 0;

      // 3. ループで一つ一つの約定を確認
      for(int i = 0; i < total_deals; i++)
      {
         // インデックスでチケット番号を取得
         ulong ticket = HistoryDealGetTicket(i);

         if(ticket > 0)
         {
            // この約定が「現在のEA(マジックナンバー)」によるものか、
            // かつ「損益が発生する決済取引」であるかを確認
            long magic = HistoryDealGetInteger(ticket, DEAL_MAGIC);
            double profit = HistoryDealGetDouble(ticket, DEAL_PROFIT);

            // マジックナンバーが一致する場合のみ加算(必要に応じてシンボルチェックも追加)
            if(magic == 123456) 
            {
               total_profit += profit;
            }
         }
      }

      Print("本日の現在の合計損益: ", total_profit);
   }
   else
   {
      Print("履歴の取得に失敗しました。");
   }
}

4. 使用上の注意点とよくあるエラー

①「注文(Order)」と「約定(Deal)」の混同

MQL5には、ユーザーが出した「注文(Order)」の履歴と、実際に売買が成立した「約定(Deal)」の履歴の2種類があります。損益計算を行いたい場合は、必ず HistoryDeal... 系の関数を使用してください。HistoryOrderSelect はあくまで「指値が通ったか・キャンセルされたか」の履歴を見るためのものです。

② サーバー時刻とローカル時刻のズレ

HistorySelect に渡す日時は、PCの時計ではなく、必ずブローカーのサーバー時刻を使用してください。TimeCurrent() を基準に計算するのが最も安全です。

③ 呼び出し頻度とパフォーマンス

HistorySelectOnTick の中で毎回呼ぶのは、履歴が膨大になると負荷がかかる原因になります。特に数千件の履歴がある口座では、「決済が発生した時だけ呼び出す」といったイベント駆動型の実装(OnTradeTransaction の活用など)を検討してください。

④ フィルターの欠如

HistorySelect は指定期間内の「すべての取引」を読み込みます。他のEAや手動トレードの履歴も含まれるため、必ずマジックナンバー(DEAL_MAGIC)や通貨ペア(DEAL_SYMBOL)でフィルタリングを行う処理を入れてください。

5. 【重要】自動売買における約定スピードと環境の罠

アルゴリズムトレードにおいて、プログラムの論理的な正しさと同じくらい重要なのが「物理的な実行環境」です。どれほど完璧なロジックを HistorySelect で構築しても、自宅のPCや一般的な回線からEAを動かしている場合、ネットワークの遅延(レイテンシ)によって致命的な損失を招くリスクがあります。FXの価格はミリ秒単位で変動しており、自宅から海外サーバーへの注文送信に数十〜数百ミリ秒を要すると、本来の計算とは異なる不利な価格で約定(スリッページ)してしまい、期待するパフォーマンスは得られません。

プロのクオンツエンジニアが極限まで約定スピードを追求するのは、コンマ数秒の遅れが長期的な期待値をマイナスに転じさせることを知っているからです。本格的な自動売買運用を行うのであれば、ブローカーのデータセンターに近いロケーションにあるFX専用VPSの導入は避けて通れません。ネットワーク遅延を最小化し、24時間安定した実行環境を確保することこそが、システムトレーダーとして生き残るための最低条件と言えます。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました