FX自動売買基礎と応用

異なる時間軸のチャートでマウスポインタを同期させる方法


グローバル変数の「Set」を指定


MQLプログラミング言語のグローバル変数について解説」では、クロスヘアラインを表示させることができました。今回は、マウスの位置を一旦グローバル変数に保存して、その保存した値を「OnTimer」で読み取りながら表示するコードに改修していきます。これにより、異なる時間軸のチャートを並べて表示した際に、マウスポインタ(クロスへアライン)の動きを同期させることができます。

参考記事:MQLプログラミング言語のグローバル変数について解説

使用するのは、グローバル変数の「Set」です。MQL4リファレンスの目次にある「Global Variables of the Terminal」→「GlobalVariableSet」を選択すると、パラメーター等を確認できます。指定するのは、変数の名前と値で、ここでは名前を「GVlauePrice」、値を「price」と「time」にします。OnChartEvent配下に次の二つの式を追記します。


GlobalVariableSet("GVlauePrice", price);
GlobalVariableSet("GVlaueTime", time);

                 
GlobalVariableSetの設定項目
nameグローバル変数名を指定
value設定する値を指定


Timer関数からグローバル変数を呼び出す


GlobalVariableSetで指定したグローバル変数をTimer関数から呼び出します。タイマーを利用するには、何秒間隔で動くタイマーなのかを宣言する必要があるので、OnInit配下に「EventSetMillisecondTimer(100);」を加えます。ここではミリ秒を表す「Millisecond」を単位として指定したので、100ミリ秒=0.1秒間隔でタイマーが動作します。同時にOnDeinit配下にタイマーを消す「EventKillTimer();」もセットで定義しましょう。

そして今度は、「Get」でグローバル変数を呼び出して値を利用します。Getのパラメーター等は、MQL4リファレンスの「Global Variables of the Terminal」→「GlobalVariableGet」を選択すると確認できます。OnTimer配下に次のように指定しましょう。変数自体は浮動小数点という型なので、「(datetime)」を記述して型を変換するのがポイントです。


double price = GlobalVariableGet("GVlauePrice");
datetime time = (datetime)GlobalVariableGet("GVlaueTime");

これで完成です。コンパイルして二つのチャートにセットすると、クロスヘアラインが同期して同じように動くことが分かります。

今回は少し特殊な使い方を紹介しましたが、例えば「インジケーターの値をグローバル変数に送って、それをEAで利用する」など、応用的な使い方も可能です。


ソースコード


今回、作成したソースコードは下記の通りです。


//+------------------------------------------------------------------+
//|                                                LineSync_demo.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
   EventSetMillisecondTimer(100);
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinit function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(0, "VLine");
   ObjectDelete(0, "HLine");
   EventKillTimer();
}
//+------------------------------------------------------------------+
//| 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[])
{
//---

//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
   double price = GlobalVariableGet("GVlauePrice");
   datetime time = (datetime)GlobalVariableGet("GVlaueTime");
   HLineCreate(0, "HLine", 0, price);
   VLineCreate(0, "VLine", 0, time);
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
//---
   if(id == CHARTEVENT_MOUSE_MOVE) {
      int x = (int)lparam;
      int y = (int)dparam;
      int win = 0;
      double price;
      datetime time;
      if (ChartXYToTimePrice(0, x, y, win, time, price)) {
         GlobalVariableSet("GVlauePrice", price);
         GlobalVariableSet("GVlaueTime", time);
      }
   }
}

//+------------------------------------------------------------------+
//| Create the vertical line                                         |
//+------------------------------------------------------------------+
bool VLineCreate(const long            chart_ID = 0,      // chart's ID
                 const string          name = "VLine",    // line name
                 const int             sub_window = 0,    // subwindow index
                 datetime              time = 0,          // line time
                 const color           clr = clrWhite,    // line color
                 const ENUM_LINE_STYLE style = STYLE_SOLID, // line style
                 const int             width = 1,         // line width
                 const bool            back = false,      // in the background
                 const bool            selection = false, // highlight to move
                 const bool            hidden = true,     // hidden in the object list
                 const long            z_order = 0)       // priority for mouse click
{
//--- if the line time is not set, draw it via the last bar
   if(!time)
      time = TimeCurrent();
//--- reset the error value
   ResetLastError();
//--- create a vertical line
   if(!ObjectCreate(chart_ID, name, OBJ_VLINE, sub_window, time, 0)) {
      /*      Print(__FUNCTION__,
                  ": failed to create a vertical line! Error code = ",GetLastError()); */
      ObjectSetInteger(chart_ID, name, OBJPROP_TIME, 0, time);
      return(false);
   }
//--- set line color
   ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
//--- set line display style
   ObjectSetInteger(chart_ID, name, OBJPROP_STYLE, style);
//--- set line width
   ObjectSetInteger(chart_ID, name, OBJPROP_WIDTH, width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
   ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);
   ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);
   ObjectSetString(chart_ID, name, OBJPROP_TOOLTIP, "¥n");
//--- successful execution
   return(true);
}

//+------------------------------------------------------------------+
//| Create the horizontal line                                       |
//+------------------------------------------------------------------+
bool HLineCreate(const long            chart_ID = 0,      // chart's ID
                 const string          name = "HLine",    // line name
                 const int             sub_window = 0,    // subwindow index
                 double                price = 0,         // line price
                 const color           clr = clrWhite,    // line color
                 const ENUM_LINE_STYLE style = STYLE_SOLID, // line style
                 const int             width = 1,         // line width
                 const bool            back = false,      // in the background
                 const bool            selection = false, // highlight to move
                 const bool            hidden = true,     // hidden in the object list
                 const long            z_order = 0)       // priority for mouse click
{
//--- if the price is not set, set it at the current Bid price level
   if(!price)
      price = SymbolInfoDouble(Symbol(), SYMBOL_BID);
//--- reset the error value
   ResetLastError();
//--- create a horizontal line
   if(!ObjectCreate(chart_ID, name, OBJ_HLINE, sub_window, 0, price)) {
      /*      Print(__FUNCTION__,
                  ": failed to create a horizontal line! Error code = ",GetLastError());*/
      ObjectSetDouble(chart_ID, name, OBJPROP_PRICE, 0, price);
      return(false);
   }
//--- set line color
   ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr);
//--- set line display style
   ObjectSetInteger(chart_ID, name, OBJPROP_STYLE, style);
//--- set line width
   ObjectSetInteger(chart_ID, name, OBJPROP_WIDTH, width);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
   ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection);
   ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order);
   ObjectSetString(chart_ID, name, OBJPROP_TOOLTIP, "¥n");
//--- successful execution
   return(true);
}
//+------------------------------------------------------------------+


本記事の監修者・HT FX


2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。


本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。



この記事をシェアする

ホーム » FX自動売買基礎と応用 » 異なる時間軸のチャートでマウスポインタを同期させる方法