ラインタッチでアラート通知するツールを作成する方法
チャート上の全てのオブジェクトを検索
この記事では、特定の線種(二点鎖線)の水平線に価格がタッチしたときにアラートを通知するツールを作る方法を紹介します。
ファイルの新規作成で「カスタムインディケータ」を選択し、ファイル名は「TouchLineAlert」とします。今回は「OnChartEvent」を使用するので、「カスタムインディケータのイベントハンドラ」の画面で「OnChartEvent」にチェックを入れて、ひな形を完成させましょう。
まずは、チャート上にある全てのオブジェクトを検索するよう、ObjectsTotal関数を使って次のfor文を記述します。
for (int i = 0; i < ObjectsTotal(0, -1); i++) {
string name = ObjectName(0, i);
検索したオブジェクトが水平線かつ線種が二点鎖線「DASHDOTDOT」だったときに処理を実行するようにしたいので、次のif文を加えます。そして、そのときのライン価格を取得するようObjectGetDouble関数を使います。
if (ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_HLINE && ObjectGetInteger(0, name, OBJPROP_STYLE) == STYLE_DASHDOTDOT){
double price = ObjectGetDouble(0, name, OBJPROP_PRICE, 0);
水平線への価格タッチ条件を指定
続いて、価格が水平線の下から上へタッチしたときと、価格が水平線の上から下へタッチしたときにアラート通知するコードを記述します。「Close[0] >= price && Close[1] < price」が下から上へのタッチ条件、「Close[0] <= price && Close[1] > price」が上から下へのタッチ条件です。アラート通知のコメントは、「通貨ペア名」と「価格情報」としましょう。
if ((Close[0] >= price && Close[1] < price) || (Close[0] <= price && Close[1] > price)){
string text = _Symbol + " Touch line. " + DoubleToString(Bid, _Digits);
Alert(text);
そして、1本の足で1回のみの通知するようにしたいので、for文の前に次のif文を追加します。
static datetime timeAlert;
if (Time[0] > timeAlert)
さらに、通知したときに現在の足の時間を入れるので、「Alert(text);」の下に次のコードを加えましょう。
timeAlert = Time[0];
break;
これでコンパイルが成功すれば、価格が二点鎖線の水平線にタッチしたときにアラートが鳴るロジックは完成です。チャートにセットしてローソク足の上に二点鎖線の水平線を引くと、アラートが通知されることが分かります。
キーボード操作で水平線の線種を変更
次に、キーボード操作で選択した水平線の線種を変更するロジックを組みます。
まず関数の外でグローバル変数を宣言します。ファイル上部の一般プロパティの下に「string NAME;」を宣言し、「OnChartEvent」配下に次のif文を記述します。これは、もしクリックしたオブジェクトが選択中だったら、そのオブジェクトの名前を覚えるという指示です。
if (id == CHARTEVENT_OBJECT_CLICK){
if (ObjectGetInteger(0, sparam, OBJPROP_SELECTED)) NAME = sparam;
}
今回はキーボードの「A」を押したときに水平線の線種変更を実行するようにします。
キーボードの「A」キーは処理的に30番が割り当てられており、「sparam」は押されたキーの番号にあたるので、「sparam」が「30」のときに処理を実行するよう、次のif文を加えます。現在の線種を取得し、選択中のオブジェクトが二点鎖線だったときは実線に、そうではなかったときは二点鎖線に変更する指示です(※変数sparamは、CHARTEVENTの種類によって、値が変化します。
各種イベントでの内容を確認したい場合は、MQL5リファレンス>イベント処理>OnChartEventを参照してください)。
if (id == CHARTEVENT_OBJECT_CLICK){
if (ObjectGetInteger(0, sparam, OBJPROP_SELECTED)) NAME = sparam;
}
if (id == CHARTEVENT_KEYDOWN){
if ((int)sparam == 30){
long style = ObjectGetInteger(0, NAME, OBJPROP_STYLE);
if (style == STYLE_DASHDOTDOT) ObjectSetInteger(0, NAME, OBJPROP_STYLE, STYLE_SOLID);
else ObjectSetInteger(0, NAME, OBJPROP_STYLE, STYLE_DASHDOTDOT);
}
}
}
これをコンパイルし、二点鎖線を選択した状態でキーボードの「A」キーを押すと実線に切り替わることが分かります。新しく加えた水平線でも同様の操作が可能です。実線の水平線へのタッチではアラートは通知されませんが、二点鎖線に設定した水平線にタッチすると通知されます。
ソースコード
今回、作成したソースコードは下記の通りです。
//+------------------------------------------------------------------+
//| aaa.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
string NAME;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
static datetime timeAlert;
if (Time[0] > timeAlert)
for (int i = 0; i < ObjectsTotal(0, -1); i++) {
string name = ObjectName(0, i);
if (ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_HLINE && ObjectGetInteger(0, name, OBJPROP_STYLE) == STYLE_DASHDOTDOT){
double price = ObjectGetDouble(0, name, OBJPROP_PRICE, 0);
if ((Close[0] >= price && Close[1] < price) || (Close[0] <= price && Close[1] > price)){
string text = _Symbol + " Touch line. " + DoubleToString(Bid, _Digits);
Alert(text);
timeAlert = Time[0];
break;
}
}
}
//--- return value of prev_calculated for next call
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 (ObjectGetInteger(0, sparam, OBJPROP_SELECTED)) NAME = sparam;
}
if (id == CHARTEVENT_KEYDOWN){
if ((int)sparam == 30){
long style = ObjectGetInteger(0, NAME, OBJPROP_STYLE);
if (style == STYLE_DASHDOTDOT) ObjectSetInteger(0, NAME, OBJPROP_STYLE, STYLE_SOLID);
else ObjectSetInteger(0, NAME, OBJPROP_STYLE, STYLE_DASHDOTDOT);
}
}
}
//+------------------------------------------------------------------+
本記事の監修者・HT FX
2013年にFXを開始し、その後専業トレーダーへ。2014年からMT4/MT5のカスタムインジケーターの開発に取り組む。ブログでは100本を超えるインジケーターを無料公開。投資スタイルは自作の秒足インジケーターを利用したスキャルピング。
EA(自動売買)を学びたい方へオススメコンテンツ

OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。
本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。