前回は 実際に注文を出す記述を、順を追って説明しました。
改めて前回の内容をおさらいをしておくと、
注文は、
・MqlTradeRequest構造体とMqlTradeResult構造体のインスタンスを宣言する。
↓
・MqlTradeRequest構造体の各メンバに必要な値を入れていく。
↓
・OrderSend関数を記述する。
というプロセスで記述していく。
ということをお伝えしました。
今回は 注文が無事約定し、有効化したポジションに対してストップロス(SL:損切り価格)とテイクプロフィット(TP:利益確定価格)を設定するプロセス についてお話ししたいと思います。
有効化したポジションにSLとTPを設定するにはTRADE_ACTION_SLTPを使う
有効化したポジションにSLとTPを設定するにはTRADE_ACTION_SLTPを使います。 この時、待機注文の修正を行うTRADE_ACTION_MODIFYとの混同に注意する必要があります。
また、前回の成行注文解説回では、SLとTPは設定しませんでしたが、そもそも論として、新規注文の時点でSLとTPは原則設定できる訳ですから、作るEAの戦略次第でコーディングが変わります。
ネッティングシステムでのSLTP設定
ネッティングシステム口座の場合、保有ポジションは1銘柄1つなのでポジションの確認は銘柄名(→.symbol)で確認します。従って、SLTP設定にあたり.positionへの値は入力不要です。
request.action =TRADE_ACTION_SLTP; // 取引操作タイプ
request.symbol =_Symbol; // シンボル
request.sl =ストップロス価格; // ポジションのStop Loss
request.tp =テイクプロフィット価格; // ポジションのTake Profit
OrderSend(request,result);
ヘッジングシステムでのSLTP設定設定
ヘッジングシステム口座の場合、1銘柄に対して複数のポジション保有が可能なので、SLTPの設定にあたっては、ポジション番号を正しく取得し.position に設定する事が必要になります。
ポジション番号の取得は、
- PositionGetTicket関数を使う。
- PositionGetInteger関数を使い、引数にPOSITION_TICKETを設定する
- MqlTradeResult構造体のメンバ変数 .orderの値を使う
などの手段を用います。
request.action =TRADE_ACTION_SLTP; // 取引操作タイプ
request.symbol =_Symbol; // シンボル
request.position=ポジション番号; // ポジション番号
request.sl =ストップロス価格; // ポジションのStop Loss
request.tp =テイクプロフィット価格; // ポジションのTake Profit
OrderSend(request,result);
実際に、SLとTPを付与する記述を書いてみる
SLTP設定に関する概略を説明したところで、実際にSLとTPを付与する記述を書いてみましょう。
※ネッティングシステム口座については、最初に説明した事以上に付け加えることもなく、現在大多数のブローカーが提供しているのヘッジングシステムであることもあり、これから先の記述は全てヘッジングシステムを前提とした記述です。
前回の成行注文解説回でつかった成り行き買い注文のコードに、SLとTPを設定する記述を追加していきます。
#property script_show_inputs
まずグローバル領域(関数の外の領域)にプロパティ命令である script_show_inputs
を記述します。この記述をしていると、スクリプト実行の前にプロパティウィンドウを表示してくれます。
ストップロスとテイクプロフィットを設定するにあたり、今回はinput変数を用います。
input int StopLoss=1000;
input int TakeProfit=1000;
void OnStart()
int型で、変数名をそれぞれStopLoss、TakeProfitとし、ポイントベース換算でSLTPを算出するので初期値は便宜的に1000としました。
※ポイントというのは、銘柄における値動きの一番小さい値を指します。ドル円などの対円通貨ペアであれば「0.001」が1ポイント、ユーロドル等の対円以外の通貨ペアでは「0.00001」が1ポイントとなっています。
続いては、新規成行注文が約定した後の記述を見ていきます。
OrderSend(request,result);
if(result.retcode==TRADE_RETCODE_PLACED ||result.retcode==TRADE_RETCODE_DONE)
{
Print("注文が成功しました。 リターンコード= ",result.retcode);
request.action = TRADE_ACTION_SLTP;
request.position = result.order;
SLとTPを設定したいので、.actionにはTRADE_ACTION_SLTPを設定します。
今回は.positionにはMqlTradeResult構造体のメンバ変数 .orderを代入しました。
成行注文の際は、オーダー番号とポジション番号は同じものが同時に割り振られるのでその性質を利用します。
※詳しいことは講座記事第61回の「メンバ変数 .orderにはオーダー番号が格納される」
の項目をご覧ください。
PositionSelectByTicket(result.order);
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
PositionSelectByTicket関数
PositionSelectByTicket関数は、引数にポジション番号を指定することによって、指定ポジションの様々な情報を取得する作業を許可する関数です。PositionSelectByTicket関数の処理が正常に行われれば、以降
PositionGetDouble()、PositionGetInteger()、PositionGetString()などの関数を使って指定ポジションの情報取得が可能になります。
先ほどもお伝えしたように、新規成行注文の際は、オーダー番号とポジション番号は同じものが同時に割り振られるのでPositionSelectByTicket関数の引数にresult.orderを記述することでポジション番号を記述した事と同じ意味になります。
なぜここで、PositionSelectByTicket関数を使っているかというと、この後SLとTPを設定する際に必要となる約定価格を取得する為です。
ポジションの約定価格はPositionGetDouble関数の引数に定数値「POSITION_PRICE_OPEN」を記述します。
取得した約定価格をdouble型の変数「openPrice」に格納し、晴れてSLTPを設定する準備が整いました。
※約定価格についてはMqlTradeResult構造体のメンバ変数 .priceを使うという方法もあります。
if文で、変数TakeProfitやStopLossに0より大きい数値が入っているかを切り分けさせたうえで、メンバ変数 .sl と.tp にそれぞれストップロスとテイクプロフィットの値を代入していきます。
if(TakeProfit > 0)request.tp=openPrice+(TakeProfit*_Point);
if(StopLoss > 0)request.sl=openPrice-(StopLoss*_Point);
OrderSend(request,result);
すでに変数「openPrice」には約定価格が代入されているので、.tpにはopenPrice+(TakeProfit*_Point)、.slにはopenPrice-(StopLoss*_Point)を代入すればいいことになります。
*_Pointというのは、定義済み変数で、現在の銘柄における、値動きの一番小さい値を取得します。ドル円などの対円通貨ペアであれば「0.001」、ユーロドル等の対円以外の通貨ペアでは「0.00001」が返ってきます。
input変数「 StopLoss」「TakeProfit」には1000が入っているので、SL、TPともに約定価格から1000ポイント(100ピプス)上下に設定されたことになります。
全体のコード
全体のコードは以下のようになっています
#property script_show_inputs
input int StopLoss=1000;
input int TakeProfit=1000;
void OnStart()
{
//MqlTradeRequest構造体とMqlTradeResult構造体のインスタンスを宣言
MqlTradeRequest request={};
MqlTradeResult result={};
request.action=TRADE_ACTION_DEAL;
request.type=ORDER_TYPE_BUY;
request.symbol=_Symbol;
request.volume=0.1;
request.type_filling=ORDER_FILLING_IOC;
request.price=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
request.sl=0;
request.tp=0;
request.deviation=3;
request.magic=1234;
OrderSend(request,result);
if(result.retcode==TRADE_RETCODE_PLACED ||result.retcode==TRADE_RETCODE_DONE)
{
Print("注文が成功しました。 リターンコード= ",result.retcode);
request.action = TRADE_ACTION_SLTP;
request.position = result.order;
PositionSelectByTicket(result.order);
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
if(TakeProfit > 0)request.tp=openPrice+(TakeProfit*_Point);
if(StopLoss > 0)request.sl=openPrice-(StopLoss*_Point);
OrderSend(request,result);
}
else Print("注文が失敗しました。リターンコード= ",result.retcode);
}
↑上記のサンプルコードを実際に実行してみると・・・↓
新規成行注文が成立し、約定価格から上下1000ポイントにSLとTPが入っている事が確認できるかと思います。
まとめ
今回は 約定したポジションに対してSLとTPを設定する記述 について解説しました。
今回の記事では以下のことを学びました
- 有効化したポジションにSLとTPを設定するにはTRADE_ACTION_SLTPを使う。
- 待機注文の修正を行うTRADE_ACTION_MODIFYとの混同に注意する。
今回は以上になります。
最後までお読みいただきありがとうございました<m(__)m>
【超入門】MQL5 EA講座 第62回「実際に注文を出すコードを書いてみる」【EAの作り方】←
→【超入門】MQL5 EA講座 第64回「ポジションをクローズする」【EAの作り方】
※ツイッターでも、
を用意していますので、よろしければご参照ください。<m(__)m>
コメント