MT5には高頻度取引の専用のトレード関数が存在します。OrderSendAsync() です。
MT5がHFTなどのティックベースのトレード戦略を開発するために最適化されているという話は、MT4とMT5の違いを比較した記事においても述べました。
OrderSendAsync() は公式レファレンスにも
The function is designed for high-frequency trading
とあるように HFT 専用に設計されていることがわかります。
ここでは OrderSendAsync() について説明し、その有効活用方法なども解説します。
Contents
基本的な使い方は OrderSend() と同じ
OrderSendAsync() の引数は以下です。MqlTradeRequest 構造体と MqlTradeResult 構造体が引数になっていて、これらの構造体の設定方法も OrderSend() と全く同じです。
bool OrderSendAsync(
MqlTradeRequest& request, // Request structure
MqlTradeResult& result // Response structure
);
MqlTradeRequest 構造体でどのようなトレード操作を行うかを設定して、MqlTradeResult 構造体で送信したリクエストの結果が返ってきます。
※ MqlTradeRequest 構造体・MqlTradeResult 構造体の使い方はわかりにくいので、こちらで詳しく解説しています。
何が違うのか?
大きな違いは、この関数では サーバーからの返答を待たずして Order を同時処理的に送れる点です。
これはどういうことかというと、本来の OrderSend() では、
(戻り値は「適切にサーバに置かれたかどうか」を示す)
▼
▼
という流れです。2) の処理に割と時間がかかるので、これが終わるまで他の処理を行うことができないのが難点です。
OrderSendAsync() のでは、2) の サーバーの処理が完了するまで 数ミリ秒~数100ミリ秒 待つ必要はなく、リクエストが実行されたかに関係なく EA内の続きの処理を行うことが出います。
したがって実行する際に以下のような差に注意する必要があるといえます。
OrderSend と仕様が異なる点 ①
「サーバーに注文が適切に置かれたか」は OrderSend() では戻り値で確認するが、
OrderSendAsync() では result 構造体のTRADE_RETCODE_PLACED 値によって確認する必要がある。
OrderSend と仕様が異なる点 ②
OrderSend() では MqlTradeResult 構造体 にて「実行されたリクエストの情報」が確認できたが、
OrderSendAsync() ではサーバーの返答を待たずに戻り値を返すので(この関数が数値を返す段階ではまだ不明な情報も多くあり)MqlTradeResult 構造体 において確認できない情報が多い。
例えばオーダーのチケット番号は MqlTradeResult 構造体の ‘order’ メンバによって確認できないこともあります(確認できることもある)
「どういう場面」で使うか
OrderSendAsync() のメリットは、OnTick() や OnTimer() 実行時に最も時間のかかる「サーバー内での処理を待つ時間」をすっ飛ばして処理を実行できる点です。
これは「ヘッジなどで高速で複数ポジションを持ちたいとき」に有効です。(アービトラージでヘッジをする際など)
例えば「ある瞬間」に 「USDJPY のロングと、EURJPY のショート」を同時に持ちたい場合、
OrderSend では1個目を送信してからサーバーの返答を待ってから2個目を送信する必要がありますが、数100ミリ秒もあればレートは大きく変化するのでおそらく本来のレートからはズレてしまいます。
OrderSendAsync ではサーバーの返答を待つ時間がないので、(ほぼ)同時処理的にオーダーを送信できます。
例えば、ペアトレ(統計的裁定取引・stat arb)や三角裁定取引で使えますね。
MT4の時代にはこれを回避するためにわざわざ EA を2個作って(疑似的に)マルチスレッドを行う必要がありましたが、MT5ではその必要はありませんね。
実際の実行時間の差
OrderSend と OrderSendAsync の実行時間の差に関して、MetaQuotes 社のCEOが過去にこちらのフォーラム内で解答をしています。
ロシア語なのでわかりにくいですが、
MT4 では 10個の注文をサーバーに送るのに 1498 ミリ秒かかったのに対して、MT5 では 31ミリ秒しかかからなかった
ということが書かれています。