ObjectCreateでオンオフボタンを作成しよう

こんにちは~。

MQLをマスターしたくて、最近寒くなってきたけど自宅で靴下はなんとなく履きたくないりょうです。

今日はチャート上にボタンを作成してインジケーターを出し入れしてみる試みです。

TOC

ボタン操作でインジケーターを表示/非表示に

普段MT4を使用している人は、様々なインジケーターを駆使してトレードをされていると思いますが、そんな中チャート上にインジケーターが複数表示されていて見づらいという方も少なくないのではないでしょうか?

りょう

わかる~

にゃんぽこ

線の色とか、太さとか、実線と点線とか使い分けてもなかなか見づらかったりするよね

今回は少しでも快適にトレードを行うため、それらのインジケーターを出し入れ出来るスイッチを作成してみました。

例として20移動平均線(SMA)をローソク足501本分表示させるインジケーターにスイッチを組み込みました。

早速ですが今回作成したソースコードがこちらです↓。

//+------------------------------------------------------------------+
//|                                                        MA_BT.mq4 |
//|                        Copyright 2022, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window

#property indicator_buffers 1

#property indicator_color1        clrRed
#property indicator_width1        3
#property indicator_type1         DRAW_LINE

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
long    chart_id = ChartID();                                            // チャートID設定
string objname = "MAButton";                                            // オブジェクト名設定
double BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
   SetIndexBuffer(0, BufMA);

//ボタン作成
   ObjectCreate(chart_id,                                                  // チャートID
                objname,                                                   // オブジェクト名
                OBJ_BUTTON,                                                // オブジェクトタイプにボタンを選択
                0,                                                         // サブウインドウ番号
                0,                                                         // 1番目の時間のアンカーポイント
                0                                                          // 1番目の価格のアンカーポイント
               );
//ボタンの位置とサイズ設定
   ObjectSetInteger(chart_id, objname, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー位置を左上に
   ObjectSetInteger(chart_id, objname, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER); // アンカー位置を左上に
   ObjectSetInteger(chart_id, objname, OBJPROP_XDISTANCE, 15);             // X座標の位置設定
   ObjectSetInteger(chart_id, objname, OBJPROP_YDISTANCE, 30);             // Y座標の位置設定
   ObjectSetInteger(chart_id, objname, OBJPROP_XSIZE, 150);                // ボタンサイズの幅設定
   ObjectSetInteger(chart_id, objname, OBJPROP_YSIZE, 50);                 // ボタンサイズの高さ設定
//ボタンの色設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrSkyBlue);       // ボタンの色設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BORDER_COLOR, clrWhite);    // ボタンの枠の色設定
//ボタンのフォント設定
   ObjectSetString(chart_id, objname, OBJPROP_FONT, "Arial");              // フォントの種別設定
   ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrBlack);           // ボタンのフォント色設定
   ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch ON");       // 表示するテキストの設定
   ObjectSetInteger(chart_id, objname, OBJPROP_FONTSIZE, 13);              // フォントサイズ設定
//オブジェクトを選択できないようにする
   ObjectSetInteger(chart_id, objname, OBJPROP_SELECTABLE, false);         // ダブルクリックでオブジェクトの選択可否設定
   ObjectSetInteger(chart_id, objname, OBJPROP_SELECTED, false);           // オブジェクトの選択状態
//その他設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BACK, false);               // オブジェクトをローソク足などの前側に設置する
   ObjectSetInteger(chart_id, objname, OBJPROP_STATE, false);              // ボタン押下状態

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   ObjectsDeleteAll(chart_id, objname);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {

   for(int i = 500; i >= 0; i--) {
      double MA = iMA( Symbol(), PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE, i );
      BufMA[i] = MA;
   }
   return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if(id == CHARTEVENT_OBJECT_CLICK) {
      if(sparam == objname ) {//sparamという変数の中に、どのオブジェクトがクリックされたかが入っている
         if(ObjectGetInteger(chart_id, objname, OBJPROP_STATE)) {
            ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch OFF");                // 表示するテキスト
            ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrLightGray);                 // フォント色
            ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrDarkSlateGray);           // ボタン色
            SetIndexStyle(0, DRAW_LINE, EMPTY, EMPTY, clrNONE);

         } else {
            ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch ON");                 // 表示するテキスト
            ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrBlack);                     // フォント色
            ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrSkyBlue);                 // ボタン色
            SetIndexStyle(0, DRAW_LINE, EMPTY, EMPTY, clrRed);
         }
      }
   }
}
//+------------------------------------------------------------------+

ボタンオブジェクト作成部分

ボタン作成

まずはOnInitを使用します。

ボタンを作成するには、オブジェクトを作るためのObjectCreate()関数を使用し、オブジェクトタイプにOBJ_BUTTONを選択します。

//ボタン作成
   ObjectCreate(chart_id,                                                  // チャートID
                objname,                                                   // オブジェクト名
                OBJ_BUTTON,                                                // オブジェクトタイプにボタンを選択
                0,                                                         // サブウインドウ番号
                0,                                                         // 1番目の時間のアンカーポイント
                0                                                          // 1番目の価格のアンカーポイント
               );



↑こちらの部分です。

4番目の引数の『サブウインドウ番号』は0にするとメインウインドウという意味です。

5、6番目の引数はオブジェクトの位置に関する引数ですが、位置に関しては後で設定するので0を入れておきます。

ムゥ

まずここでボタンを作成して、その下に細かい設定を書いてくのにゃ

ボタンの位置とサイズ設定

//ボタンの位置とサイズ設定
   ObjectSetInteger(chart_id, objname, OBJPROP_CORNER, CORNER_LEFT_UPPER); // コーナー位置を左下に
   ObjectSetInteger(chart_id, objname, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER); // アンカー位置を左下に
   ObjectSetInteger(chart_id, objname, OBJPROP_XDISTANCE, 15);             // X座標の位置設定
   ObjectSetInteger(chart_id, objname, OBJPROP_YDISTANCE, 30);             // Y座標の位置設定
   ObjectSetInteger(chart_id, objname, OBJPROP_XSIZE, 150);                // ボタンサイズの幅設定
   ObjectSetInteger(chart_id, objname, OBJPROP_YSIZE, 50);                 // ボタンサイズの高さ設定



ボタンを作成した後は、ボタンの位置とサイズを決めましょう。

1、2番目のオブジェクトプロパティ『OBJPROP_CORNER』『OBJPROP_ANCHOR』について、何がコーナー位置で何がアンカー位置なのか、最初は良くわからないと思います。

りょう

うん わからん


『OBJPROP_CORNER』は、チャート上のどこに配置するか、『OBJPROP_ANCHOR』はオブジェクトのどこを基準に配置するかという設定です。

例えばこのようなオブジェクトをチャート画面に設置したいとします↓。



今回のソースコードは、コーナー・アンカーともに『○○_LEFT_UPPER』、つまり左上を指定しています↓。



つまりチャートの左上に、オブジェクトの左上を基準として配置するようになります↓。



もし、オブジェクトの基準を『ANCHOR_RIGHT_LOWER』、つまり右下を基準に配置するとこうなってしまいます↓。



 

りょう

オブジェクトよ いずこへ

にゃんぽこ

コーナーとアンカーは間違えないようにね


3、4番目は先ほど決めたチャート画面の左上を0として、X軸・Y軸がどれだけ離れた位置にオブジェクトを配置するかです。

5、6番目はオブジェクトサイズの高さと幅を決めます。

ボタンの色、フォント設定

//ボタンの色設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrSkyBlue);       // ボタンの色設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BORDER_COLOR, clrWhite);    // ボタンの枠の色設定
//ボタンのフォント設定
   ObjectSetString(chart_id, objname, OBJPROP_FONT, "Arial");              // フォントの種別設定
   ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrBlack);           // ボタンのフォント色設定
   ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch ON");       // 表示するテキストの設定
   ObjectSetInteger(chart_id, objname, OBJPROP_FONTSIZE, 13);              // フォントサイズ設定



これらでボタンの色、フォントの字体や色・サイズなどを決めています。

りょう

ちゃんと『ボタンの色』と『フォントの色』の2つを決めないとね

ムゥ

忘れそうにゃ

オブジェクトを選択できないようにする

//オブジェクトを選択できないようにする
   ObjectSetInteger(chart_id, objname, OBJPROP_SELECTABLE, false);         // ダブルクリックでオブジェクトの選択可否設定
   ObjectSetInteger(chart_id, objname, OBJPROP_SELECTED, false);           // オブジェクトの選択状態



今回のオブジェクト作成は、チャート上にボタンを固定しておいておきたいので、ダブルクリックでオブジェクトが選択できないようにしておきます。

ムゥ

地味に大事にゃ

その他設定

//その他設定
   ObjectSetInteger(chart_id, objname, OBJPROP_BACK, false);               // オブジェクトをローソク足などの前側に設置する
   ObjectSetInteger(chart_id, objname, OBJPROP_STATE, false);              // ボタン押下状態



『OBJPROP_BACK』はtrueにすると、ボタンよりローソク足の方が前に来ます。

今回はボタンを前に越させたいのでfalseです。

『OBJPROP_STATE』はボタンが押されているかどうかの状態を示すプロパティです。

今回は初期値をfalseにしています。

クリック操作部分

OnCalculateでは、MAを表示させる処理を行っているだけです。

今回は20SMAを501本分表示させています。

りょう

特筆すべき点はなし

今回のボタンオブジェクトの話では、先ほどのOnInit内と、OnChaetEventが重要になります。

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if(id == CHARTEVENT_OBJECT_CLICK) {
      if(sparam == objname ) {//sparamという変数の中に、どのオブジェクトがクリックされたかが入っている
         if(ObjectGetInteger(chart_id, objname, OBJPROP_STATE)) {
            ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch OFF");                // 表示するテキスト
            ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrLightGray);                 // フォント色
            ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrDarkSlateGray);           // ボタン色
            SetIndexStyle(0, DRAW_LINE, EMPTY, EMPTY, clrNONE);

         } else {
            ObjectSetString(chart_id, objname, OBJPROP_TEXT, "MA Switch ON");                 // 表示するテキスト
            ObjectSetInteger(chart_id, objname, OBJPROP_COLOR, clrBlack);                     // フォント色
            ObjectSetInteger(chart_id, objname, OBJPROP_BGCOLOR, clrSkyBlue);                 // ボタン色
            SetIndexStyle(0, DRAW_LINE, EMPTY, EMPTY, clrRed);
         }
      }
   }
}



OnChartEventでは何かイベントが起こったときに処理する内容を書くわけですが、今回は『ボタンオブジェクトがクリックされたら』処理を実行するため、『if(id == CHARTEVENT_OBJECT_CLICK)』こちらを記載します。

ボタンオブジェクトがクリックされたら、ボタン内の表示を『MA Switch OFF』にして、ボタンの色を『DarkSlateGray』に変更してなど、オブジェクトにどのような変更を加えるか記載するほか、SetIndexStyleでMAを描画していたバッファの色の設定をclrNONE、つまり色無しにすることでMAの表示をなくしています。


その下には、さらにもう一度押したらボタンが元に戻り、MAの表示も元に戻る処理を記載しておきます。

ムゥ

これでクリックするごとにMAがオンオフするインジケーターが完成したのにゃ!

完成品を見てみよう

実際に作成したインジケーターがこちらです↓。


りょう

一見、何の変哲もない移動平均線

にゃんぽこ

左上に何やらボタンがあるのう


左上のボタンをクリックすると↓。


ムゥ

消えたにゃ

このようにオンオフするインジケーターがつくれました。

インジケーターの表示/非表示を選択してチャートを見やすくしたい方や、チャート上にオブジェクトを設置したいと思っている方は参考になれば幸いです。

りょう

お試しくだされ

TOC
閉じる