MT4の標準機能では、複数のボジションを一度に全部決済することが出来ないようです。ないものは作れば良いというのがMT4の最大の特徴ではないでしょうか?
今回は、チャート上にボタンを配置して、そのボタンを押すと保有しているポジションを全部決済するEAの作り方を説明します。
EAは基本的に自動売買をするものですが、チャート上にボタンなどを配置することができるので、全決済ボタンなどを作ることも可能です。
EAのテンプレートを作る

赤枠の新規作成ボタンを押します。

エキスパートアドバイザ(テンプレート)を選んで次へのボタンを押します。

名前を入力して次へのボタンを押します。「Experts」はフォルダ名で「CloseButton]がEA名になります。

「OnChartEvent」にチェックをつけて次へのボタンを押します。

完了ボタンを押すとテンプレートの完成です。
全決済ボタンの配置
OnInit部分にボタンを配置するためのコードを書きます。
| int OnInit() { ObjectCreate("btnClose", OBJ_BUTTON, 0, 0, 0); ObjectSet("btnClose", OBJPROP_XDISTANCE, 90); ObjectSet("btnClose", OBJPROP_YDISTANCE, 30); ObjectSet("btnClose", OBJPROP_XSIZE, 80); ObjectSet("btnClose", OBJPROP_YSIZE, 25); ObjectSet("btnClose", OBJPROP_CORNER, 1); ObjectSet("btnClose", OBJPROP_FONTSIZE, 10); ObjectSet("btnClose", OBJPROP_COLOR, Black); ObjectSet("btnClose", OBJPROP_BGCOLOR, DarkGray); ObjectSetString(0, "btnClose", OBJPROP_TEXT, "全決済"); ObjectSetString(0, "btnClose", OBJPROP_FONT, "MS ゴシック"); return(INIT_SUCCEEDED); } |
3行目から13行目までがボタンの配置関連の処理です。
3行目 ここでボタンを作っています。
4行目と5行目はボタンの位置の設定です。
6行目と7行目はボタンの大きさの設定です。
8行目でボタンの位置の基準を右上にしています。 0にすると左上が基準になります。
9行目 ボタンのフォントサイズです。
10行目 フォントの色です。
11行目 ボタンの色です。
12行目 ボタンに表示するテキストです。
13行目 フォントの種類です。
ボタンの詳しい説明は、「EAにボタン、テキストボックス、ラベルを配置する方法」をご覧ください。
全決済ボタンの削除
| void OnDeinit(const int reason) { ObjectDelete("btnClose"); } |
EAがチャートから削除された時にボタンを削除するための処理です。
ボタンが押されたかの判断をする
OnChartEvent部分にボタンが押されたかの判断をする処理を書きます。
| void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(sparam == "btnClose") { Sleep(100); ObjectSet("btnClose", OBJPROP_STATE, False); } } |
6行目でボタンが押されたかの判断をしています。
9行目はボタンを押したように見せるためのスリープです。
10行目は凹んだ状態のボタンをもとに戻す処理です。
全決済の処理
上で書いたボタンが押された時の処理のところに全決済の処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(sparam == "btnClose") { for(int i = OrdersTotal() -1; i >= 0; i--) { OrderSelect(i, SELECT_BY_POS); if(OrderType() == OP_BUY) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Bid, 5, Yellow); } else if(OrderType() == OP_SELL) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Ask, 5, Yellow); } } Sleep(100); ObjectSet("btnClose", OBJPROP_STATE, False); } } |
8行目から21行目までが全決済をするための処理です。
8行目 オーダー数分ループさせます。「OrdersTotal()」はMQLの標準関数で現在のオーダー数を返します。(オーダー数には、ボジションの他に新規の待機注文も含まれます。)
マイナスループにしているのは、大きなインデックス番号から決済させるためです。これをプラスにしてしまうと複数のポジションを持っている場合、インデックス番号の一番小さい0を決済すると残りのボジションのインデックス番号が繰り下がって、決済できないポジションが出てしまうからです。
10行目 「OrderSelect(i, SELECT_BY_POS)」はオーダーの選択です。ここでオーダーを選択することで、選択したオーダーの情報の取得や処理などが出来るようになります。2つ目の引数は、オーダーの選択方法でインデックス番号かチケット番号を選ぶことが出来ます。「SELECT_BY_POS」はインデックス番号での選択になります。1つ目の引数「i」はループ内の変数で、インデックス番号を設定しています。
11行目 「OrderType()」は、選択しているオーダーの種類を取得することが出来ます。if文で「OrderType()」が「OP_BUY」(買いポジション)の時に処理をするようにしています。
13行目 「RefreshRates()」は定義済み変数や配列のデータを更新する関数です。ここでは決済処理をする前に「Bid」の値を最新にするために使っています。
14行目 ここが決済の処理です。OrderCloseの引数は左から、チケット番号、ロット数、価格、スリッページ、チャート上に表示される矢印の色です。OrderTicket()とOrderLots()は、選択しているオーダーのチケット番号とロット数を返す関数です。「Bid」は現在の売り価格です。買いポジションの決済なので「Bid」を設定します。次の「5」はスリッページでポイント単位で設定します。
16行目と19行目は、売りポジションの処理です。買いポジションの説明とほとんど同じで「OP_BUY」と「Bid」の2か所が「OP_SELL」と「Ask」の売りポジションようになっています。
今回、説明したのは全決済をするための最低限のコードです。通貨ペアやマジックナンバーなどは一切見ていないため、保有している全てのポジションを決済します。
全コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | //+------------------------------------------------------------------+ //| CloseButton.mq4 | //| Copyright 2018, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2018, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { ObjectCreate("btnClose", OBJ_BUTTON, 0, 0, 0); ObjectSet("btnClose", OBJPROP_XDISTANCE, 90); ObjectSet("btnClose", OBJPROP_YDISTANCE, 30); ObjectSet("btnClose", OBJPROP_XSIZE, 80); ObjectSet("btnClose", OBJPROP_YSIZE, 25); ObjectSet("btnClose", OBJPROP_CORNER, 1); ObjectSet("btnClose", OBJPROP_FONTSIZE, 10); ObjectSet("btnClose", OBJPROP_COLOR, Black); ObjectSet("btnClose", OBJPROP_BGCOLOR, DarkGray); ObjectSetString(0, "btnClose", OBJPROP_TEXT, "全決済"); ObjectSetString(0, "btnClose", OBJPROP_FONT, "MS ゴシック"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectDelete("btnClose"); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(sparam == "btnClose") { for(int i = OrdersTotal() -1; i >= 0; i--) { OrderSelect(i, SELECT_BY_POS); if(OrderType() == OP_BUY) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Bid, 5, Yellow); } else if(OrderType() == OP_SELL) { RefreshRates(); OrderClose(OrderTicket(), OrderLots(), Ask, 5, Yellow); } } Sleep(100); ObjectSet("btnClose", OBJPROP_STATE, False); } } //+------------------------------------------------------------------+ |
これをコンパイルすると55行目、59行目、64行目の3か所に警告メッセージが出ます。
OrderSelect、OrderCloseには戻り値があって、成功すると「true」で失敗すると「false」が返されます。本来は、この戻り値を使ってエラー処理などをするのですが、今回は戻り値を使っていないので警告メッセージが出ています。自動売買ではなくボタンなので、このままでもそれほど問題ないのではないかと思います。
※今回、説明した全決済ボタンは、EAが使えない口座では使うことが出来ません。
当サイトに掲載している情報やサンプルコードを利用した結果によって生じるいかなる損害、損失について当サイトは一切の責任を負いません。サンプルコードにはバグなどがある可能性もあります。当サイトの情報やサンプルコードの利用は、自己責任でお願いします。
おすすめ記事
リアル口座のトレード収支結果です。 EA名:KonohaUSDJPY 通貨ペア:USDJPY 使用FX業者:OANDA JAPAN(東京サーバー) バージョン:1.00 パラメーター:すべて初期値 約定日時… |
EAの長期間のバックテストをするにはMT4にヒストリカルデータを入れる必要があります。 今回は、一番簡単にできるMetaQuotes社のヒストリカルデータの入れ方と、FXDDのヒストリカルデータをダウンロードしてインポー… |
関連記事
今回は、マジックナンバー別の口座履歴をcsvファイルに出力させるスクリプトの作り方を説明します。 目次 スクリプトのテンプレートの作り方口座履歴を出力するスクリプトの作り方今回説明するスクリプトの仕様ファイ… |
前回の「全決済ボタンのEAに通貨ペアとマジックナンバーの処理を追加する」で説明した全決済ボタンのEAに、売りボタンと買いボタンをつけてみます。 売り注文や買い注文は、MT4の標準機能で出来るので、ボタンを作る意味はあまり… |
今回は、EAにボタン、テキストボックス、ラベルの配置方法と使い方を説明します。 目次 ボタンの配置方法テキストボックスの配置方法ラベルの配置方法オブジェクトの削除ボタン、テキストボックス、ラベルの使い方全コ… |
MT4にはデバッグ機能が備わっています。前は無かったのですがBuild 600から実装されました。 目次 デバッグ時の通貨ペアと時間足の変更ブレークポイント変数の確認デバッグの注意点コンパイル時のエラーの探… |
今回は、「全決済ボタンをEAで作ってみる」で説明したEAに、通貨ペアとマジックナンバーの処理を追加します。 目次 通貨ペアの処理を追加するマジックナンバーの処理を追加するパラメーターの追加マジックナンバーの… |