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

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

MQL5におけるOrderSendは、取引サーバーに対して注文(売買、注文の変更、取消)を送信するための最も基本的かつ重要な関数です。MQL4時代とは異なり、MQL5のOrderSendは「MqlTradeRequest」という構造体に注文内容を詰め込み、「MqlTradeResult」という構造体で実行結果を受け取るという、非常にオブジェクト指向に近い設計になっています。

実務開発において、初心者が最もつまずきやすいのは「リクエスト構造体の初期化不足」「実行結果の判定ミス」です。単に注文を出すだけでなく、サーバーから返ってきたリターンコードを解析し、再送処理(リトライ)を行うか、あるいはエラーとして停止させるかを判断するロジックを組むことが、堅牢なEA(自動売買ソフト)開発への第一歩となります。

2. 構文と戻り値

OrderSend関数の構文は非常にシンプルですが、引数に渡す構造体の中身が重要です。

構文

bool OrderSend(
   MqlTradeRequest&  request,      // 注文内容を格納した構造体
   MqlTradeResult&   result       // 実行結果が格納される構造体
);

パラメーター

  1. request: MqlTradeRequest型の構造体。注文の種類(成行・指値)、通貨ペア、ロット数、価格、マジックナンバーなどを指定します。
  2. result: MqlTradeResult型の構造体。サーバーからの応答(注文受理の可否、注文ID、約定価格など)が格納されます。

戻り値

  • true: 基本的なチェックを通過し、サーバーへリクエストが送信されたことを意味します(※約定を保証するものではありません)。
  • false: ターミナル側でエラーが発生し、リクエストが送信されなかったことを意味します。この場合、GetLastError()で詳細なエラーコードを確認する必要があります。

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

以下は、最も頻繁に使用される「成行買い注文」を出すための実戦的なサンプルコードです。構造体をゼロ初期化し、必要な値を正確にセットする流れを確認してください。

void OnStart()
{
    // 構造体の宣言
    MqlTradeRequest request;
    MqlTradeResult  result;

    // 構造体をゼロで初期化(ゴミデータによる誤作動を防止)
    ZeroMemory(request);
    ZeroMemory(result);

    // 注文内容の設定
    request.action       = TRADE_ACTION_DEAL;         // 取引の実行(成行注文)
    request.symbol       = _Symbol;                   // 実行チャートの通貨ペア
    request.volume       = 0.1;                       // ロット数
    request.type         = ORDER_TYPE_BUY;            // 買い注文
    request.price        = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // 現在の買値
    request.deviation    = 10;                        // 許容スリッページ(ポイント)
    request.magic        = 123456;                    // マジックナンバー(EA識別用)
    request.comment      = "Sample Order";            // 注文コメント
    request.type_filling = ORDER_FILLING_IOC;         // 約定方式(業者により異なる)

    // 注文の送信
    if(!OrderSend(request, result))
    {
        // 送信自体に失敗した場合
        Print("OrderSend error: ", GetLastError());
    }
    else
    {
        // サーバーからの応答を確認
        if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
        {
            Print("注文が成功しました。チケット番号: ", result.order);
        }
        else
        {
            // サーバー側で拒否された場合(証拠金不足や価格変更など)
            Print("注文が拒否されました。リターンコード: ", result.retcode);
        }
    }
}

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

開発時に必ず意識すべきポイントがいくつかあります。

  • 価格の正規化(NormalizeDouble): 注文価格は通貨ペアの桁数に合わせる必要があります。不適切な桁数で送信すると「Invalid Price(無効な価格)」エラーが発生します。
  • Filling Mode(約定方式)の選択: ブローカーによって ORDER_FILLING_IOCORDER_FILLING_FOK など、受け付ける方式が異なります。自身の環境でどの方式が許可されているか、SymbolInfoInteger関数等で事前に取得する設計が望ましいです。
  • リターンコードの判別: OrderSendtrueを返しても、result.retcode10009(DONE)以外であれば、注文は完了していません。特に「リクオート(10004)」や「価格変更(10006)」への対処は、実際の運用で必須となります。

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

アルゴリズムトレードにおいて、ロジックの優位性と同じくらい重要なのが「実行環境のレイテンシ(遅延)」です。自宅のPCから一般的なインターネット回線を通じて注文を出す場合、プロバイダー経由の複雑な経路や家庭内LANのノイズにより、サーバーに注文が届くまでに数十〜数百ミリ秒の遅延が発生します。このわずかな遅延が、相場急変時には「スリッページによる利益の削り取り」や「約定拒否」という致命的な損失を招きます。

クオンツエンジニアの視点から言えば、コンマ一秒を争うFX市場で勝ち続けるためには、取引サーバーが設置されているデータセンター(ロンドンやニューヨークなど)に物理的に近い「専用のVPS(仮想専用サーバー)」の利用が不可欠です。ネットワーク遅延を極限まで排除し、24時間安定した高速通信環境を確保することこそが、システムトレーダーにとって最も期待値の高い投資となります。

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

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

コメント

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