OnTradeTransactionで注文状態を管理する:MT5 EAを「発注して終わり」にしないイベント駆動設計

MT5 EAでOnTradeTransactionを使い、Request、Order、Deal、Positionを状態遷移として管理する方法を解説。OrderSendだけに依存せず、約定確認と重複発注防止を含むイベント駆動型の注文管理設計を整理します。

注文関数の戻り値だけでは実際の約定状態を判断できない

MT5 EAでは、シグナル発生後にOrderSendを実行し、戻り値がtrueなら注文処理を完了したと考えたくなる。しかしOrderSendのtrueは、基本的なチェックを通過して取引要求が処理対象として受け付けられたことを示すものであり、約定そのものを保証しない。実際の結果はMqlTradeResultのretcodeや、その後に発生する取引イベントまで確認する必要がある。

ライブ運用では通信、サーバー処理、部分約定、注文変更などが介在する。そのため、シグナル発生とポジション成立を同一処理として扱わず、取引状態の変化を追跡する設計が重要になる。

RequestからPositionまでを状態遷移として扱う

一つの買い要求でも、内部ではRequestの処理、Orderの生成、Dealの発生、Orderの履歴化、Positionの生成といった複数のトランザクションが発生する。OnTradeTransactionは、これらの取引口座上の変化をイベントとして受け取るためのハンドラである。

EA内部では例えばREQUEST_SENT、ORDER_ACTIVE、PARTIALLY_FILLED、FILLED、POSITION_OPEN、CANCELED、REJECTEDなどの状態を持たせると管理しやすい。

重要なのは「注文を送った」という内部フラグと「ポジションが存在する」という事実を分離することだ。

到着順序を前提にしたロジックを作らない

MQL5の仕様では、TradeTransactionイベントの到着順序は保証されていない。さらにOnTradeTransactionを処理している間にも、ターミナル側では新しい取引トランザクションの処理が進む。

したがって「ORDER_ADDの次には必ずDEAL_ADDが来る」といった順序依存のコードは避けるべきである。

イベントを受け取るたびにticket、order、deal、position、request_idなどを確認し、現在の状態から更新可能かを判定する。イベントそのものを状態とみなすのではなく、イベントを材料に内部Stateを更新する設計が適している。

TRADE_TRANSACTION_REQUESTでは結果コードを確認する

TRADE_TRANSACTION_REQUESTを受け取った場合は、MqlTradeRequestとMqlTradeResultを利用して要求の処理結果を確認できる。requestとresultの情報が取引要求に対応するのは、このTransaction Typeの場合である。

ここではretcodeを確認し、受付、拒否、価格変更、証拠金不足などを分類する。単純なboolだけで成功・失敗を管理しないことがポイントになる。

重複発注をState Machineで防ぐ

実運用EAで起きやすい問題の一つが重複注文である。OnTickで売買条件が連続して成立すると、最初の注文がPositionとして認識される前に次の注文要求を送る可能性がある。

対策として、シグナル発生時にIDLEからORDER_PENDINGへ状態を変更し、未処理Requestが存在する間は新規発注を禁止する。その後、OnTradeTransactionで約定や拒否を確認してPOSITION_OPENまたはIDLEへ遷移させる。

この方式なら、ティック速度とサーバー応答速度の差を売買ロジックから切り離せる。

OrderとPositionを混同しない

MQL5ではOrderは取引要求、Dealは実際に成立した取引、PositionはDealの結果として形成される保有状態という違いがある。特にNetting口座では1銘柄につき原則1つのPositionとなり、Hedging口座では同一銘柄に複数Positionを保有できる。

EAを複数の口座タイプへ展開する場合、Order TicketとPosition Ticketを同一IDとして管理しない設計が必要になる。

イベント処理は軽量に保つ

OnTradeTransactionのイベントキューは1024要素であり、ハンドラ内の処理に時間がかかりすぎると、新しいイベントによって古いイベントが置き換えられる可能性がある。

そのため、イベント内では状態更新と必要最低限のログ記録に留め、重い計算やインジケーター分析はOnTickやOnTimerなど別処理へ分離する方が安全である。

まとめ

MT5 EAの注文管理では、OrderSendを実行した瞬間を取引完了と考えず、Request、Order、Deal、Positionを異なる状態として管理することが重要になる。

OnTradeTransactionを中心にState Machineを構築すれば、約定確認、注文拒否、部分約定、非同期処理、重複発注といったライブ環境特有の問題を売買ロジックから分離できる。シグナル生成と取引状態管理を独立させることが、EAをバックテスト用コードから実運用システムへ発展させる基盤になる。

ABOUTこの記事をかいた人

当サイトは、システムトレードに関する専門的な知識、技術、経験を皆様と共有することで、真剣なトレーダーの方々にインスピレーション(アイデアの源泉)の供給をいたします。トレーダーの競争力強化に焦点をあて、トレーディングシステムの構築を目的としてその普及に貢献します。 詳細は「概要とサービス内容」をご覧下さい。 ご要望はこちらで承ります。