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

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

MQL5におけるOnTrade関数は、取引サーバー上で「トレードに関する何らかの変化」が生じた際に呼び出されるイベントハンドラーです。具体的には、注文の送信、約定、ストップロスの変更、ポジションの決済といった、口座の状態に変化があった瞬間に自動的に実行されます。

実務開発において、初心者が最もつまずきやすいポイントは「OnTrade自体は『何が起きたか』の情報を教えてくれない」という点です。この関数はあくまで「変化があった」という通知(ベル)を鳴らすだけであり、具体的にどの通貨ペアが約定したのか、あるいは注文がキャンセルされたのかといった詳細は、関数内で自分自身でポジションや履歴をスキャンして確認する必要があります。

プロの現場では、注文を出した後に「本当に約定したか」を監視するリトライロジックの起点や、ポジション数が変わったタイミングで損切り(SL)や利確(TP)を再設定する処理などに活用されます。

2. 構文と戻り値

OnTrade関数の構造は非常にシンプルです。引数はなく、戻り値も必要ありません。

void OnTrade();
  • : void(戻り値なし)
  • パラメーター: なし
  • 発生条件: 注文リスト、公開ポジションリスト、取引履歴のいずれかに変更があった場合。

なお、より詳細な取引データ(トランザクションタイプや注文の詳細)を直接取得したい場合は、OnTradeTransactionという別の関数を使用しますが、口座全体の整合性をチェックするだけであれば、このシンプルなOnTradeで十分事足ります。

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

以下のコードは、OnTradeイベントが発生するたびに、現在保有しているポジションの合計数を確認し、ポジションに変化があった場合のみログを出力する実用的なテンプレートです。

//+------------------------------------------------------------------+
//|                                              SimpleTradeWatch.mq5|
//|                                  Copyright 2024, Quant Engineer  |
//+------------------------------------------------------------------+
#property strict

// 前回のポジション数を保持するグローバル変数
int last_position_count = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // 起動時のポジション数を初期値として取得
    last_position_count = PositionsTotal();
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Trade event handler                                              |
//+------------------------------------------------------------------+
void OnTrade()
{
    // 1. 現在のポジション総数を取得
    int current_position_count = PositionsTotal();

    // 2. 前回チェック時とポジション数が異なるか確認
    if(current_position_count != last_position_count)
    {
        Print("【トレードイベント検知】ポジション数が変化しました。");
        Print("以前の数: ", last_position_count, " -> 現在の数: ", current_position_count);

        // 3. ここに具体的な処理を記述(例:SL/TPの自動付与など)
        CheckAndSetStops();

        // 4. ポジション数を更新
        last_position_count = current_position_count;
    }
}

// 独自の関数例:ポジションにSL/TPが入っているか確認する
void CheckAndSetStops()
{
    for(int i = 0; i < PositionsTotal(); i++)
    {
        ulong ticket = PositionGetTicket(i);
        if(PositionSelectByTicket(ticket))
        {
            // ここでポジションの詳細(マジックナンバー等)を確認し、
            // 必要に応じて修正注文を出すロジックを組む
        }
    }
}

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

  1. 無限ループの罠: OnTrade内で注文や変更(OrderSendPositionModify)を行うと、その操作自体が再びOnTradeイベントを発生させます。条件分岐を正しく書かないと、関数が何度も呼び出され、過剰なリクエストでサーバーから遮断される恐れがあります。
  2. 実行頻度への配慮: 非常に多くの注文を出すEAの場合、OnTradeは短時間に何度も呼ばれます。関数内で重い計算処理やファイル操作を行うと、EA全体のパフォーマンスが低下し、肝心の約定判断に遅れが生じます。
  3. 情報の欠落: OnTradeが発生した瞬間、必ずしもすべての取引履歴が最新の状態に更新されているとは限りません。極めて稀ですが、ネットワークの状況により、サーバー側の反映とイベントの呼び出しに僅かなズレが生じることがあります。重要な判定の前には、一瞬の待機(Sleep)を入れるか、複数回チェックする工夫が必要です。

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

アルゴリズムトレードにおいて、ロジックの優位性以上に収益を左右するのが「ネットワーク遅延(レイテンシ)」です。自宅のPCでMT5を動かし自動売買を行うことは、プロの視点からは極めてリスクが高い行為と言わざるを得ません。家庭用回線はプロバイダー経由の複雑な経路を辿るため、ミリ秒単位の遅延が積み重なり、チャート上の価格と実際の約定価格が乖離する「スリッページ」を頻発させます。

特に相場急変時には、この数ミリ秒の差が致命的な損失に直結します。プロレベルの約定スピードを実現し、EAのポテンシャルを最大限に引き出すには、取引サーバーに物理的に近いデータセンター内に設置された「専用VPS」の導入が必須です。安定した電源、24時間の稼働保証、そして極限まで抑えられたネットワーク遅延。これらのインフラを整えることは、勝つための「最低限の投資」と言えるでしょう。

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

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

コメント

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