見出し画像

【MT4】複数ポジションを一括決済する「全決済」ボタンの作り方

MT4で複数ポジション持ってる時に、一気に決済したいって思う事ありませんか?

・指標発表で大きく動いた時
・注目している通貨が節目にタッチした時
・ナンピンポジションと合算でプラスに転じた時

手動で決済してると、間に合わない時ないですか?

合算でプラスになってたはずなのに、一つずつ決済してる間にマイナスに・・・なんて事があったりしたので、「全決済」出来るボタンを作りました。

画像1

全決済ボタンの作り方

まずは、ボタンの作り方ですね。

MT4でボタンを作るには、ObjectCreateを使います。

int OnInit()
{
  //全決済ボタン
   ObjectCreate("btnClose", OBJ_BUTTON, 0, 0, 0);
   ObjectSet("btnClose", OBJPROP_XDISTANCE, 90);
   ObjectSet("btnClose", OBJPROP_YDISTANCE, 90);
   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);
}

ボタンの作成は一度だけ実行されればよいため、OnInit関数の中に記載します。

OnInit関数はEAの実行時に1回だけ実行されます。

ですので、一度しか実行する必要がない処理はOnInit関数の中に記載します。

btnCloseってところが、オブジェクトの名前になります。

ここは任意の名前にして大丈夫です。

OBJPROP_XDISTANCE、OBJPROP_YDISTANCEの2つが表示位置の設定になります。

今回は画面の右側に表示したかったため、90としてます。

この数字を変える事で、自分の好きな場所に表示する事が出来ますよ。

ボタンが押された時の動作を作る

ボタンが出来たので、次はボタンが押された時の動作を作成します。

ボタンが押された動作はOnChartEvent関数内に記載します。

まずは全容です。

void OnChartEvent(const int id,
                 const long &lparam,
                 const double &dparam,
                 const string &sparam)
{

   if(sparam == "btnClose" && id==CHARTEVENT_OBJECT_CLICK)
   {
       for(int i = OrdersTotal() -1; i >= 0; i--)
       {
       
           OrderSelect(i, SELECT_BY_POS);
           if(OrderType() == OP_BUY)
           {
               RefreshRates();
               if(OrderClose(OrderTicket(), OrderLots(), SymbolInfoDouble(OrderSymbol(), SYMBOL_BID), 5, Yellow) == false)
               {
                   Print(GetLastError());
                   continue;
               }
           }
           else if(OrderType() == OP_SELL)
           {
               RefreshRates();
               if(OrderClose(OrderTicket(), OrderLots(), SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK), 5, Yellow) == false)
               {
                   Print(GetLastError());
                   continue;
               }
           } 
       }
   
       Sleep(100);
       ObjectSet("btnClose", OBJPROP_STATE, False);
   }
}

それでは、一つずつ説明していきます。

if(sparam == "btnClose")

このIF文でどのボタンが押されたかを判断します。

btnCloseってのがオブジェクト名です。OnInit関数内でボタンを作成した際につけたオブジェクト名になります。

今回はボタンが一つしかないですが、他にもボタン(オブジェクト)がある時は、ここのIF文を増やす事でいろいろな処理が出来るようになります。

for(int i = OrdersTotal() -1; i >= 0; i--)

OrderTotal関数は保有ポジション数を取得する事が出来ます。

今回は全決済したいので、この保有してるポジション数分処理を行う事とにします。

if(OrderType() == OP_BUY)

買いポジションか売りポジションかを判断してます。

買いポジションの時はBidの値、売りポジションの時はAskの値で決済するようにしてます。

if(OrderClose(OrderTicket(), OrderLots(), SymbolInfoDouble(OrderSymbol(), SYMBOL_BID), 5, Yellow) == false)

OrderCloseが決済処理になります。

全決済するので、OrderLots()でオーダーしてるロットすべて決済するようにしてます。

5って数字が許容スリッページ数になります。

すべってずれるのが嫌な場合は、この数字を小さくすると良いです。

が、小さくしすぎるといつまでたってもすべって決済されない事態になります。

「Yellow」は決済された個所に表示される矢印の色ですね。

買いと、売りとで色を変えるとかするとチャートで実績を確認する時にわかりやすくてよいですよ!

clr_NONEとすると、何も表示されなくなります。

チャートがごちゃごちゃするのが嫌なかたは、clr_NONEとして下さい。


       ObjectSet("btnClose", OBJPROP_STATE, False);

ボタンを押される前の状態に戻す処理になります。

ボタンって押したら戻る物って思うでしょ?

けど、ちゃんとボタンを戻すって命令をしないと戻らないんですよ。

プログラムって指示した通りに動いてくれますが、

「ボタンは押したら普通戻るでしょ」って気を利かして動いてはくれません。

ってことでちゃんとボタンを押す前の状態戻す処理を入れましょう。

まとめ

これでMT4で全決済するボタンの完成です。

「スリッページの許容を超えて決済できなかった」

「通信エラー」

など、いろいろなエラーで決済できない事もありますので、

押した後に必ずポジションの確認してくださいね。

※短期間での大量注文をNGにしてる業者もあるようです。
そのような業者の場合、連続での注文はエラーになる場合もありますので、決済されたかの確認は必ず行ってください。

私が実際に自分で使用してるボタンですので、大丈夫とは思いますが
ご使用は自己責任でお願いします。

自分で書くのめんどくさいって人のために、全ソースコードを販売してます。あとは、コンパイルするだけって状態です。

ここから先は

2,817字
この記事のみ ¥ 500

この記事が気に入ったらサポートをしてみませんか?