MQLプログラミング言語のグローバル変数について解説
CHART_EVENT_MOUSE_MOVEを利用
この記事で解説するのは、グローバル変数についてです。一般的にグローバル変数とは、関数の外で宣言された変数のことを指します。具体的な説明に進む前に、まずはひな形を作成します。ここではファイル名を「LineSync_demo」とし、「カスタムインディケータのイベントハンドラ」では「OnTimer」と「OnChartEvent」の両方を選択します。
今回利用するのは、「端末のグローバル変数」です。作った変数に対してどのチャートからでもアクセスできるようになる他、一度作るとパソコンやMT4を落としても4週間はデータが保持されるという特徴があります。ここでは端末のグローバル変数を用いて、チャート間でデータをやり取りするクロスヘアラインの同期ツールを作っていきましょう。
まずはクロスヘアラインを表示させるために、「ChartEvent」を作成します。MQL4リファレンスで「ChartEvent」を検索し、検索結果の中から「Types of Chart Events」をクリックして「CHART_EVENT_MOUSE_MOVE」を利用します。パラメーターは、一つ目の「lparam」がマウスのX座標の位置、二つ目の「dparam」がY座標の位置です。そして今回は使いませんが、三つ目の「sparam」はマウスのボタンが押されているかの状態を示します。
MOUSE_MOVEのパラメーターの値 | |
---|---|
idパラメーターの値 | CHARTEVENT_MOUSE_MOVE |
lparamパラメーターの値 | X座標 |
dparamパラメーターの値 | Y座標 |
sparamパラメーターの値 | マウスボタンの状態を説明するビットマスクの文字列値 |
ChartXYToTimePriceでXY座標を時間と価格に変換
MOUSE_MOVEを使う場合は、OnInit関数配下に次のように宣言をしておく必要があります。
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
そしてOnChartEvent内でパラメーターから座標を取得し、その座標をチャート上の価格データと時間データに変換します。使う関数は「ChartXYToTimePrice」です。これはXYをtimeとpriceに変換するという関数です。
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);
}
}
これでXY座標を価格データと時間データに変換することができます。
変換データを用いて垂直線と水平線を表示
ChartXYToTimePriceを使ってXY座標を価格データと時間データに変換できました。続いては、その変換されたデータを利用してクロスヘアラインの縦線、横線を引いてみます。
利用するサンプルコードは、MQL4リファレンスからコピーします。MQL4リファレンスの目次にある「Constants, Enumerations and Structures」→「Objects Constants」→「Object Types」を選択すると、オブジェクトの一覧が表示されるので、その中から縦線の「OBJ_VLINE」と横線の「OBJ_HLINE」のコードをコピーし、ファイルに貼り付けます。
そして、OnChartEvent配下にHLineCreateとVLineCreateのパラメーターを設定します。HLineCreateではチャートIDは「0」、名前は「HLine」、windowは「0」、最後は「price」とします。同様にVLineCreateもチャートは「0」、名前は「VLine」、windowは「0」、最後は「time」とします。その他のパラメーターに関しては、初期設定の値を使うので省略しても構いません。
HLineCreate(0, "HLine", 0, price);
VLineCreate(0, "VLine", 0, time);
これでコンパイルすると、垂直線や水平線が表示されるようになります。
マウスの動きにラインを追従させる
垂直線や水平線を表示できましたが、一度表示したらそれで終了する初期設定になっているので、マウス位置に合わせて最新の値を反映するように改修します。VLineCreate配下に「ObjectSetInteger(chart_ID, name, OBJPROP_TIME, 0, time);」、HLineCreate配下に「ObjectSetDouble(chart_ID, name, OBJPROP_PRICE, 0, price);」の一文をそれぞれ追加します。
//--- 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);
}
//--- 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);
}
これでマウスに合わせて垂直線と水平線が動くようになりました。あとは各ラインが選択された状態になっているので、VLineCreateとHLineCreateのパラメーター「selection」のところを「true」から「false」に変更して、選択を解除します。また、一度作られたラインが消えないようにもなっているので、インジケーターを削除・再読み込み・コンパイルしたときなどにそれが消えるようOnDeinit関数を用いて次のように設定しておきます。
//+------------------------------------------------------------------+
//| Custom indicator deinit function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0, "VLine");
ObjectDelete(0, "HLine");
}
なお、このままではマウスをチャート上で止めた際にライン位置の価格情報が出るようになっています。それを出さないようにするには、各ラインのパラメーターに次の一文を追加しましょう。
ObjectSetString(chart_ID, name, OBJPROP_TOOLTIP, "\n");
これでクロスヘアラインは完成です。
マウスポインタ(クロスへアライン)は完成しましたが、このままでは異なる時間軸のチャートを並べて表示した際に同期しません。同期させる方法については、以下のコンテンツを御覧ください。
本記事の監修者・HT FX
2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。
本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。