目次 MqlTradeRequest構造体のフィールドの中には4つのENUM項目があります。 と宣言 and 初期化すると、上記4フィールドは次のようになります。
という状態になっています。 MqlTradeRequest構造体の各フィールドのうち、必ず指定しなくてはならないフィールドはExecution Modeによって異なります。そこで、Execution Modeについて少し触れておきます。 Execution Modeは自分で選べるものではありません。「使用しているFX業者」「通貨ペア」によって決まっています。Execution Modeを調べてみます。 ヘルプでMqlTradeRequestのページを見ると、各Execution Modeで必ず指定しなくてはならないフィールドは次のとおりです。 Execution ModeがMARKETとEXCHANGEの場合、priceフィールドとdeviationフィールドは無視されますが、ソースコードを簡潔にするために、これらのフィールドに値をセットしてもよいとMQL5.comに書かれています。 この方がすっきりしていて良いですね。 MQL5.comによると、FX業者のサーバー設定によっては、新たなポジションを持つ時に、同時にSL(損切価格)やTP(利確価格)を指定することを禁止している場合があるそうです。
{ }で初期化した直後の状態
action、type、type_filling、type_timeの4つです。ENUM_TRADE_REQUEST_ACTIONS action;
ENUM_ORDER_TYPE type;
ENUM_ORDER_TYPE_FILLING type_filling;
ENUM_ORDER_TYPE_TIME type_time;
MqlTradeRequest request = {};
request.action = 0
request.type = 0
request.type_filling = 0
request.type_time = 0
「MqlTradeRequest構造体(1)」に書いたとおり、actionフィールドに入るenum定数の中には 0 に相当するものが無いので、現状では何も指定していないのと同じです。
一方、type、type_filling、type_timeには、以下のように 0 に相当するものがあります。
// ENUM_ORDER_TYPEに割り当てられている値
ORDER_TYPE_BUY = 0
ORDER_TYPE_SELL = 1
ORDER_TYPE_BUY_LIMIT = 2
ORDER_TYPE_SELL_LIMIT = 3
ORDER_TYPE_BUY_STOP = 4
ORDER_TYPE_SELL_STOP = 5
ORDER_TYPE_BUY_STOP_LIMIT = 6
ORDER_TYPE_SELL_STOP_LIMIT = 7
ORDER_TYPE_CLOSE_BY = 8
// ENUM_ORDER_TYPE_FILLINGに割り当てられている値
ORDER_FILLING_FOK = 0
ORDER_FILLING_IOC = 1
ORDER_FILLING_BOC = 3
ORDER_FILLING_RETURN = 2
// ENUM_ORDER_TYPE_TIMEに割り当てられている値
ORDER_TIME_GTC = 0
ORDER_TIME_DAY = 1
ORDER_TIME_SPECIFIED = 2
ORDER_TIME_SPECIFIED_DAY = 3
よって、request = {}で初期化した場合、type = ORDER_TYPE_BUY
type_filling = ORDER_FILLING_FOK
type_time = ORDER_TIME_GTC
Execution Modeを調べる
Executionには次の4つがあります。SYMBOL_TRADE_EXECUTION_REQUEST
SYMBOL_TRADE_EXECUTION_INSTANT
SYMBOL_TRADE_EXECUTION_MARKET
SYMBOL_TRADE_EXECUTION_EXCHANGE
(備考)文字数が多いので、以後「REQUEST」「INSTANT」「MARKET」「EXCHANGE」と表記します。
void OnStart()
{
ENUM_SYMBOL_TRADE_EXECUTION executionMode =
(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_EXEMODE);
printf("Execution Mode = %s", EnumToString(executionMode));
}
上記スクリプトを実行したら、次のように表示されました。Execution Mode = SYMBOL_TRADE_EXECUTION_MARKET
このことから、私が上記スクリプトを実行した通貨ペアのExecution Modeは「MARKET」だと分かります。
ちなみに、コードを使わなくてもExecution Modeを調べることは可能です。「気配値表示」ウィンドウを右クリック → 「仕様」を選ぶ → [執行」欄を見る
Execution Modeごとの必須フィールド
「MARKET」または「EXCHANGE」の場合
•action
•symbol
•volume
•type
•type_filling
「magic」や「comment」も指定可能
「REQUEST」または「INSTANT」の場合
•action
•symbol
•volume
•type
•type_filling
•price
•sl
•tp
•deviation
「magic」や「comment」も指定可能
しかし、MQL5.comにある表を見ると、Execution Modeが REQUESTやINSTANTの場合でも sl, tp, deviation は(必須ではなく)オプションになっています(はて?)。
// the table below is quoted from
https://www.mql5.com/en/book/automation/experts/experts_market_buy_sell
Field | Request Instant Exchange Market
=============+===============================================
action | * * * *
-------------+-----------------------------------------------
symbol | * * * *
-------------+-----------------------------------------------
volume | * * * *
-------------+-----------------------------------------------
type | * * * *
-------------+-----------------------------------------------
type_filling | * * * *
-------------+-----------------------------------------------
price | * *
-------------+-----------------------------------------------
sl | + + + +
-------------+-----------------------------------------------
tp | + + + +
-------------+-----------------------------------------------
deviation | + +
-------------+-----------------------------------------------
magic | + + + +
-------------+-----------------------------------------------
comment | + + + +
* は必須フィールド、 + はオプションフィールド
priceフィールドとdeviationフィールド
つまり、Execution ModeがMARKETとEXCHANGEの場合、これらのフィールドに値を指定しても意味はないけれど、実害もありません。
<情報源>
https://www.mql5.com/en/book/automation/experts/experts_market_buy_sell
初めてMqlTradeRequest構造体を使った頃は、Execution ModeがREQUESTとINSTANTの場合に応じたif文を書いていました。たとえば、次のような感じです。// Execution Modeを取得
ENUM_SYMBOL_TRADE_EXECUTION executionMode =
(ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_EXEMODE);
MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = orderVolume;
request.type = orderType;
request.type_filling = fillPolicy;
request.magic = orderMagic;
//-------------------------------------------------------
// Execution modeが INSTANT または REQUESTの場合
//-------------------------------------------------------
if(executionMode == SYMBOL_TRADE_EXECUTION_INSTANT ||
executionMode == SYMBOL_TRADE_EXECUTION_REQUEST ) {
request.sl = slPrice;
request.tp = tpPrice;
request.deviation = 10;
request.price = orderPrice;
}
しかし、Execution ModeがMARKETやEXCHANGEの場合にpriceやdeviationに値をセットしても実害がないのなら、次のように書けば済みます。MqlTradeRequest request = {};
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = orderVolume;
request.type = orderType;
request.type_filling = fillPolicy;
request.magic = orderMagic;
request.sl = slPrice;
request.tp = tpPrice;
request.deviation = 10;
request.price = orderPrice;
slフィールド、tpフィールドの注意点
<情報源>
https://www.mql5.com/en/book/automation/experts/experts_market_buy_sell
この場合、slフィールドやtpフィールドに値を設定せずに注文を出し、(約定して)ポジションを持った後で、修正注文(SLの設定やTPの設定)を出すことになります。
ちなみに、「私が使っている業者ではどのようになっているのだろうか?」と思ったので、デモ口座を使って実験してみました。
成行買い注文を出すのと同時にSL・TPを送信したところ、問題なくSL・TPが設定されました。どうやら新規注文と同時にSL・TPを指定することは禁じられていないようです。
私の考えは次のとおりです。<特定の業者だけを利用する場合>
新規注文時にSLやTPを送信して問題ないか実験する。
問題が無ければ、新規注文時にSLやTPを設定する。
<不特定多数の業者を利用する場合>
・新規注文時はslフィールドとtpフィールドは 0.0 にしておく。
・(約定して)ポジションを持ってから、そのポジションに対してSLやTPを設定する。