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

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

MQL5におけるHistoryOrderGetDoubleは、決済済み、またはキャンセル済みの「注文(Order)」に関する実数型(double)のデータを取得するための関数です。

実務において、初心者が最もつまずきやすいポイントは、「注文(Order)」「約定(Deal)」「ポジション(Position)」の区別です。
注文(Order): 売買の「指示」(指値や成行の依頼)。
約定(Deal): 注文が実行された「結果」。
ポジション: 約定によって発生した「持ち高」。

HistoryOrderGetDoubleは、あくまで「過去の注文(指示内容)」に焦点を当てた関数です。例えば、指値注文が実際にどの価格で予約されていたのか、あるいは成行注文の際に指定した初期ボリューム(数量)はいくらだったのかを確認する際に使用します。

EA(自動売買プログラム)の開発では、「意図した価格と実際の約定価格にどれだけの乖離(スリッページ)があったか」を分析したり、複雑なナンピンロジックにおいて過去の注文価格をベースに次の指値を計算したりする際に極めて重要な役割を果たします。

2. 構文と戻り値

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

double HistoryOrderGetDouble(
   ulong                         ticket_number,     // 注文チケット番号
   ENUM_ORDER_PROPERTY_DOUBLE    property_id        // プロパティの種類
);

パラメーター

  1. ticket_number: 取得したい履歴注文のチケット番号を指定します。
  2. property_id: 取得したい情報の種類を「ENUM_ORDER_PROPERTY_DOUBLE」列挙型から指定します。

主なプロパティID

  • ORDER_PRICE_OPEN: 注文時の価格(指値価格など)。
  • ORDER_VOLUME_INITIAL: 注文時の初期ロット数。
  • ORDER_VOLUME_CURRENT: まだ約定していない残りのロット数。
  • ORDER_PRICE_STOPLIMIT: ストップリミット注文の価格。

戻り値

指定したプロパティの値をdouble型で返します。データの取得に失敗した場合は 0.0 を返します。

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

この関数を使用する前には、必ず HistorySelect 関数を呼び出して、履歴をメモリに読み込んでおく必要があります。以下のコードは、最後に決済・終了した注文の指値価格とロット数を取得する例です。

void OnStart()
{
    // 1. 履歴全体を選択(全期間を対象にする例)
    if(!HistorySelect(0, TimeCurrent()))
    {
        Print("履歴の取得に失敗しました。");
        return;
    }

    // 2. 履歴にある注文の総数を取得
    int totalOrders = HistoryOrdersTotal();

    if(totalOrders > 0)
    {
        // 3. 最後に終了した注文のチケット番号を取得(インデックスは 0 から始まるため -1 する)
        ulong ticket = HistoryOrderGetTicket(totalOrders - 1);

        if(ticket > 0)
        {
            // 4. HistoryOrderGetDoubleを使用して情報を取得
            double openPrice   = HistoryOrderGetDouble(ticket, ORDER_PRICE_OPEN);
            double initialVol  = HistoryOrderGetDouble(ticket, ORDER_VOLUME_INITIAL);
            string symbol      = HistoryOrderGetString(ticket, ORDER_SYMBOL);

            // 5. 結果を出力
            PrintFormat("注文チケット: #%I64u", ticket);
            PrintFormat("通貨ペア: %s", symbol);
            PrintFormat("注文価格: %.5f", openPrice);
            PrintFormat("初期ロット: %.2f", initialVol);
        }
    }
    else
    {
        Print("履歴に注文が見つかりませんでした。");
    }
}

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

① HistorySelectの実行忘れ

最も多いミスは、HistorySelectHistorySelectByPosition を呼ばずにこの関数を実行することです。これを忘れると、関数は常に 0.0 を返し、バグの原因になります。

② 約定価格(Deal Price)との混同

ORDER_PRICE_OPEN で取得できるのは、あくまで「注文した時の価格」です。実際にいくらで約定したかを知りたい場合は、HistoryDealGetDouble 関数を使用する必要があります。スリッページを計算したい場合は、この「注文価格」と「約定価格」の差を比較することになります。

③ 削除された指値注文の扱い

期限切れや手動で削除された指値注文(Pending Order)も履歴に含まれます。これらと実際に約定に至った注文を区別するには、HistoryOrderGetIntegerORDER_STATE を確認するなどの処理を併用してください。

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

プロレベルのアルゴリズムトレードにおいて、プログラムのロジック以上に収益を左右するのが「実行環境のレイテンシ(遅延)」です。自宅のPCや一般的な光回線でEAを稼働させることは、F1レースに軽自動車で参戦するようなものです。FXサーバーは通常、世界各地のデータセンター(ロンドンやニューヨークなど)に設置されており、物理的な距離がある自宅PCからの注文は、届くまでに数十〜数百ミリ秒のロスが発生します。このわずかな遅延の間に価格が変動し、不利な価格での約定(ネガティブ・スリッページ)を招き、バックテストでは勝てていても実運用では資金を削られる致命的な原因となります。

約定スピードを極限まで高め、ロジック通りのパフォーマンスを引き出すには、取引サーバーに物理的に近い場所に位置する「専用VPS」の導入が不可欠です。低遅延なネットワーク環境を構築することで、注文のパケットがミリ秒単位で高速化され、激しい相場変動時でも狙った価格を逃さず捉えることが可能になります。システマティックに利益を積み上げるエンジニアにとって、VPSはコストではなく、勝率を安定させるための必須の投資と言えるでしょう。

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

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

コメント

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