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

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

MQL5における「HistoryDealGetInteger」は、過去に行われた特定の約定(Deal)から整数型のプロパティ(約定チケット番号、マジックナンバー、約定時刻、売買種別など)を取得するための関数です。

MetaTrader 5(MT5)の設計思想は、MT4の「注文=ポジション」という単純な構造とは大きく異なります。「注文(Order)が出され、それが成立して約定(Deal)となり、その結果としてポジション(Position)が形成される」という3段階のプロセスを辿ります。

実務開発において、この関数は以下のような場面で不可欠です。
決済理由の特定: ポジションがTP(利確)で閉じたのか、SL(損切り)で閉じたのかを履歴から判定する。
自作EAの注文管理: 履歴からマジックナンバーを照合し、自身のEAによる過去のパフォーマンスを計算する。
約定タイミングの取得: エントリーから決済まで、ミリ秒単位で正確な時間を把握する。

初心者が特につまずきやすいのは、「履歴を選択(HistorySelect等)」してからでないと、この関数で値を取得できないという点です。メモリ上の履歴データベースにアクセスする前に、まず検索範囲を指定する「前準備」が必要であることを覚えておきましょう。

2. 構文と戻り値

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

long HistoryDealGetInteger(
   ulong                         ticket_number,     // 約定チケット番号
   ENUM_DEAL_PROPERTY_INTEGER    property_id        // プロパティ識別子
);

パラメーター

  1. ticket_number: 取得したい約定のチケット番号を指定します。
  2. property_id: 取得したい情報の種類を ENUM_DEAL_PROPERTY_INTEGER 列挙型から指定します。

主なプロパティ識別子

  • DEAL_TICKET: 約定チケット番号
  • DEAL_ORDER: この約定を生成した注文番号
  • DEAL_TIME: 約定時刻(秒単位)
  • DEAL_TYPE: 売買種別(DEAL_TYPE_BUY, DEAL_TYPE_SELLなど)
  • DEAL_ENTRY: 約定のタイプ(IN=新規、OUT=決済、INOUT=ドテン)
  • DEAL_MAGIC: EAのマジックナンバー

戻り値

指定したプロパティの値を long 型で返します。エラーが発生した場合は「0」を返すため、詳細なエラー情報は GetLastError() で確認します。

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

以下は、直近に発生した約定(決済など)のマジックナンバーと約定タイプを特定し、ターミナルに出力する実用的なサンプルコードです。

void OnDeinit(const int reason)
{
   // 履歴データの取得範囲を「現在から過去1日間」に設定
   datetime end = TimeCurrent();
   datetime start = end - PeriodSeconds(PERIOD_D1);

   // 1. まず履歴を選択する必要がある
   if(HistorySelect(start, end))
   {
      // 2. 履歴内の全約定数を取得
      int totalDeals = HistoryDealsTotal();

      // 3. 最後に発生した約定を取得(インデックスは 0 から始まるため -1)
      if(totalDeals > 0)
      {
         ulong dealTicket = HistoryDealGetTicket(totalDeals - 1);

         if(dealTicket > 0)
         {
            // 4. HistoryDealGetIntegerで詳細情報を取得
            long magic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
            long type  = HistoryDealGetInteger(dealTicket, DEAL_TYPE);
            long entry = HistoryDealGetInteger(dealTicket, DEAL_ENTRY);

            PrintFormat("約定チケット: %I64u", dealTicket);
            PrintFormat("マジックナンバー: %d", magic);

            // 約定タイプ(買い・売り)の判定
            string strType = (type == DEAL_TYPE_BUY) ? "買い" : "売り";
            PrintFormat("売買種別: %s", strType);

            // エントリー区分(新規・決済)の判定
            if(entry == DEAL_ENTRY_IN) Print("区分: 新規エントリー");
            if(entry == DEAL_ENTRY_OUT) Print("区分: 決済");
         }
      }
   }
   else
   {
      Print("履歴の取得に失敗しました。");
   }
}

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

① HistorySelectの呼び出し忘れ

HistoryDealGetInteger を単体で呼び出しても、MT5の内部メモリには履歴がロードされていません。必ず HistorySelect() または HistorySelectByPosition() を事前に実行してください。

② チケット番号の渡し間違い

引数には「注文番号(Order Ticket)」ではなく「約定番号(Deal Ticket)」を渡す必要があります。これらはMT5では厳密に区別されています。HistoryDealGetTicket(index) で取得したチケット番号を使うのが確実です。

③ 型のキャスト

戻り値はすべて long 型です。マジックナンバーや時間はそのままでも扱えますが、列挙型(ENUM_DEAL_TYPE など)として扱いたい場合は、必要に応じてキャスト(型変換)を行ってください。
例: ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE);

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

アルゴリズムトレードにおいて、プログラムのロジックと同じ、あるいはそれ以上に重要なのが「実行環境」です。自宅のPCや一般的な光回線でEAを運用することは、プロのクオンツの視点からは非常にリスクが高いと言わざるを得ません。家庭用回線では物理的な距離に起因するネットワーク遅延(レイテンシ)が発生し、数ミリ秒の遅れが「スリッページ」を招き、バックテスト通りの利益を削り取ってしまうからです。

特にMT5はミリ秒単位の高速執行に対応しているため、その恩恵を最大化するには、FX業者の取引サーバーと同じデータセンター内、あるいは極めて近い距離に設置された「専用のVPS(仮想専用サーバー)」が必須です。約定スピードを極限まで高めることは、無駄なコストを抑えるための「守りの投資」であり、自動売買で長期的に生き残るための最低条件です。物理的な距離の壁を克服して初めて、あなたの書いたコードが真のポテンシャルを発揮することになります。

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

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

コメント

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