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

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

MQL5におけるHistoryOrderSelectは、取引履歴の中から特定の「注文(Order)」を選択し、その詳細情報(注文種別、価格、有効期限など)にアクセスできるようにするための関数です。

実務開発において、初心者が最もつまずきやすいのが「注文(Order)」「約定(Deal)」「ポジション(Position)」の違いです。MQL5では、エントリーの指示を出したものが「注文」、それが執行された結果が「約定」、その結果保有している状態が「ポジション」と明確に区別されています。

HistoryOrderSelectは、すでに約定して消滅した注文や、有効期限切れでキャンセルされた「過去の注文」を追跡する際に使用します。例えば、「直前に出した指値注文がなぜキャンセルされたのか?」や「注文時の指定価格と実際の約定価格にどれほどの乖離(スリッページ)があったのか?」を分析する際に不可欠な関数です。

2. 構文と戻り値

HistoryOrderSelectの構文は非常にシンプルです。

bool HistoryOrderSelect(
   ulong  ticket      // 注文チケット番号
);
  • 引数:ticket
    選択したい注文のチケット番号(一意の識別子)を指定します。
  • 戻り値:bool型
    注文の選択に成功した場合は true、失敗した場合は false を返します。

この関数を実行して true が返ってくると、その注文データがプログラム内部のキャッシュに読み込まれます。その後、HistoryOrderGetIntegerHistoryOrderGetDouble といった関数を使って、具体的な注文内容を取得できるようになります。

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

以下は、最後に送信した注文のチケット番号から、その注文が「現在どのような状態(約定済みかキャンセルかなど)」にあるかを確認する実用的なコード例です。

void OnStart()
{
    // 例:直近の注文チケット番号を取得(実際は注文送信時の戻り値などから取得します)
    ulong lastTicket = 501234567; 

    // 履歴から指定したチケット番号の注文を選択
    if(HistoryOrderSelect(lastTicket))
    {
        // 注文情報の取得
        long type     = HistoryOrderGetInteger(lastTicket, ORDER_TYPE);      // 注文種別
        double price  = HistoryOrderGetDouble(lastTicket, ORDER_PRICE_OPEN); // 注文価格
        long state    = HistoryOrderGetInteger(lastTicket, ORDER_STATE);     // 注文の状態
        string symbol = HistoryOrderGetString(lastTicket, ORDER_SYMBOL);     // 通貨ペア

        Print("--- 注文履歴の詳細 ---");
        PrintFormat("通貨ペア: %s", symbol);
        PrintFormat("注文価格: %f", price);

        // 注文状態の判別
        switch((ENUM_ORDER_STATE)state)
        {
            case ORDER_STATE_FILLED:
                Print("状態: 全数量約定済み");
                break;
            case ORDER_STATE_CANCELED:
                Print("状態: ユーザーまたはシステムによりキャンセル");
                break;
            case ORDER_STATE_EXPIRED:
                Print("状態: 有効期限切れ");
                break;
            default:
                PrintFormat("状態: その他 (%d)", state);
                break;
        }
    }
    else
    {
        // 選択に失敗した場合(履歴に存在しない、またはチケット番号の間違い)
        PrintFormat("チケット番号 %d の選択に失敗しました。エラーコード: %d", 
                    lastTicket, GetLastError());
    }
}

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

開発時に注意すべき点は以下の通りです。

  1. HistorySelectの実行が必要な場合がある
    通常、チケット番号を直接指定する HistoryOrderSelect は単体で動作しますが、インデックス(番号順)で履歴を走査する場合は、あらかじめ HistorySelect(from_date, to_date) を呼び出して、指定期間の履歴をメモリにロードしておく必要があります。
  2. 「約定(Deal)」と混同しない
    「利益がいくら出たか?」を知りたい場合に HistoryOrderSelect を使っても、注文時の価格は分かりますが、決済の利益額は分かりません。損益計算には HistoryDealSelect を使用してください。
  3. チケット番号の有効性
    注文がまだ「待機注文(Pending Order)」として生きている間は、HistoryOrderSelect ではなく OrderSelect を使用します。履歴に入った(注文が終了した)後でないと、この関数では選択できません。

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

アルゴリズムトレードにおいて、HistoryOrderSelect を使って緻密なロジックを組んだとしても、実行環境が貧弱であればすべてが無に帰します。特に、自宅のPCや一般的な光回線でEAを運用することは、クオンツの視点からは極めてリスクが高いと言わざるを得ません。家庭用回線では、FXサーバーとの通信に数十〜数百ミリ秒の「レイテンシ(遅延)」が発生し、そのわずかな間に価格が変動して深刻なスリッページを引き起こすからです。

プロの現場では、1ミリ秒の遅延が致命的な損失に直結することを常識として捉えています。極限まで約定スピードを高め、ロジック通りのパフォーマンスを発揮させるためには、取引サーバーに物理的に近いデータセンターに設置された「専用VPS」の導入が不可欠です。安定した電源、24時間の稼働保証、そして超低遅延なネットワーク環境。これらが揃って初めて、あなたのプログラムは本来の期待値を叩き出すことが可能になります。

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

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

コメント

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