前日の高値・安値をチャートに水平線で表示するインジケーターを作成します。

この記事のコードは、`ObjectCreate`や`ObjectSet`といったオブジェクト操作関数が古い書き方(chart_id引数を省略した旧式のシグネチャ)で書かれています。今のMQL4でもコンパイルは通りますが、非推奨(レガシー)扱いの関数のため、将来のMT4ビルドで警告が出たり、複数チャートを同時に扱う場面で挙動が不安定になるリスクがあります。この記事では、現行の書き方に統一したコードを紹介します。

前日の高値・安値を表示するインジケーター

前日の高値・安値を表示するインジケーターを作成していきたいと思います。

メタエディタ(MetaEditor)を立ち上げる

メタエディタ(MetaEditor)を立ち上げましょう。「ファイル」→「新規作成」→「カスタムインジケーター」の順に進み、今回は名前を「HL-line」で作成します。

グローバル変数を記述する

グローバル変数を記述しましょう。

  • 前日の高値を格納する変数:Yhigh
  • 前日の安値を格納する変数:Ylow

の2つ用意しましょう。

double Yhigh;//前日高値の変数
double Ylow;//前日安値の変数
Copy

これでグローバル変数の記述は完了です。

OnDeinit()関数を記述する

OnDeinit()関数を記述しましょう。OnDeinit()関数を記述することでインジケーターを削除すると表示が消えます。

今回は高値のYhighlineと安値のYlowlineの2本のラインを削除するように記述します。

ObjectDelete(0, "Yhighline");//Yhighlineを削除
ObjectDelete(0, "Ylowline");//Ylowlineを削除

ObjectDelete(name)という1引数だけの書き方も動きますが、最初のチャートID(0を指定すれば現在のチャート)を明示する2引数版が現行の書き方です。これでOnDeinit()関数の記述は完了です。

OnCalculate()関数を記述する

OnCalculate()関数を記述します。

Yhighには前日の高値の関数を格納します。Ylowには前日の安値の関数を格納します。

Yhigh = iHigh(NULL, PERIOD_D1, 1);//前日高値
Ylow  = iLow(NULL, PERIOD_D1, 1);//前日安値

shiftを1にすることで「1つ前の確定した日足」、つまり前日のデータを取得しています。

Period()とは時間足のことで、W1は週足という意味で、週足以上の足を表示しないようにします。

if (Period() < PERIOD_W1)

ObjectDeleteでは過去の必要ではなくなった水平ラインを削除して初期化しています。こうすることで、毎回同じ名前のオブジェクトが重複して残ることを防いでいます。

ObjectDelete(0, "Yhighline"); //前日高値ラインの初期化

ObjectCreateではラインの情報を記載します。チャートID, オブジェクト名, オブジェクトタイプ, ウィンドウ, 時間, 価格という順番です。

ObjectCreate(0, "Yhighline", OBJ_HLINE, 0, Time[0], Yhigh); //ObjectCreate(チャートID, オブジェクト名, オブジェクトタイプ, ウィンドウ, 時間, 価格);

色や線の種類は、ObjectSetInteger()で設定します。元記事にあったObjectSet()も動きますが非推奨のため、こちらを使いましょう。

ObjectSetInteger(0, "Yhighline", OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, "Yhighline", OBJPROP_COLOR, clrWhite);

高値と同様に安値も同じように記述します。

//前日安値ラインの描写
ObjectDelete(0, "Ylowline");//前日安値ラインの初期化
ObjectCreate(0, "Ylowline", OBJ_HLINE, 0, Time[0], Ylow);
ObjectSetInteger(0, "Ylowline", OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, "Ylowline", OBJPROP_COLOR, clrWhite);

これでOnCalculate()関数の記述は完了です。

    Yhigh = iHigh(NULL, PERIOD_D1, 1);//前日高値
    Ylow  = iLow(NULL, PERIOD_D1, 1);//前日安値

    if (Period() < PERIOD_W1)//週足か月足の場合は描写しない
    {
       //前日高値ラインの描写
       ObjectDelete(0, "Yhighline"); //前日高値ラインの初期化
       ObjectCreate(0, "Yhighline", OBJ_HLINE, 0, Time[0], Yhigh);
       ObjectSetInteger(0, "Yhighline", OBJPROP_STYLE, STYLE_SOLID);
       ObjectSetInteger(0, "Yhighline", OBJPROP_COLOR, clrWhite);

       //前日安値ラインの描写
       ObjectDelete(0, "Ylowline");//前日安値ラインの初期化
       ObjectCreate(0, "Ylowline", OBJ_HLINE, 0, Time[0], Ylow);
       ObjectSetInteger(0, "Ylowline", OBJPROP_STYLE, STYLE_SOLID);
       ObjectSetInteger(0, "Ylowline", OBJPROP_COLOR, clrWhite);
    }
Copy

コンパイル

コンパイルしましょう。MetaEditorの「コンパイル」(Ctrl+F7)で「0 error(s), 0 warning(s)」になることを確認し、チャートにドラッグ&ドロップして白いラインが2本表示されていたら完成です。

MQL 前日の高値・安値インジケーター 作成

ソースコード全体

HL-lineのソースコード全体は以下に記載してあります。ObjectCreate/ObjectSet/ObjectDeleteをすべて現行のchart_id引数付きシグネチャに統一済みです。

//+------------------------------------------------------------------+
//|                                                      HL-line.mq4 |
//|                     Copyright 2020, FX-EA System Project Creator |
//|                        https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, FX-EA System Project Creator"
#property link      "https://creator.fx-ea-system-project.com/"
#property version   "1.01"
#property strict
#property indicator_chart_window

double Yhigh;//前日高値の変数
double Ylow;//前日安値の変数

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectDelete(0, "Yhighline");//Yhighlineを削除
   ObjectDelete(0, "Ylowline");//Ylowlineを削除
  }

//+------------------------------------------------------------------+
//| 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[])
  {
   Yhigh = iHigh(NULL, PERIOD_D1, 1);//前日高値
   Ylow  = iLow(NULL, PERIOD_D1, 1);//前日安値

   if(Period() < PERIOD_W1)//週足か月足の場合は描写しない
     {
      //前日高値ラインの描写
      ObjectDelete(0, "Yhighline"); //前日高値ラインの初期化
      ObjectCreate(0, "Yhighline", OBJ_HLINE, 0, Time[0], Yhigh);
      ObjectSetInteger(0, "Yhighline", OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, "Yhighline", OBJPROP_COLOR, clrWhite);

      //前日安値ラインの描写
      ObjectDelete(0, "Ylowline");//前日安値ラインの初期化
      ObjectCreate(0, "Ylowline", OBJ_HLINE, 0, Time[0], Ylow);
      ObjectSetInteger(0, "Ylowline", OBJPROP_STYLE, STYLE_SOLID);
      ObjectSetInteger(0, "Ylowline", OBJPROP_COLOR, clrWhite);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Copy

まとめ

前日の高値・安値を水平線で表示するインジケーターの作り方を、現行のオブジェクト関数シグネチャに統一したコードとあわせて紹介しました。

関連記事