今回は、チャート上に残り時間を表示するインジケーターを作成していきたいと思います。

チャート上に残り時間を表示するインジケーター

今回は、チャート上に残り時間を表示するインジケーターを作成していきたいと思います。

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

メタエディタ(MetaEditor)を立ち上げましょう。今回は名前を「Nokori-Timer」で作成します。

パラメーターを記述する

パラメーターを記述しましょう。オブジェクトのフォントサイズと色を決めます。

input int FontSize = 20;//フォントサイズ20
input color FontColor = clrYellow;//黄色
Copy

OnInit()関数に記述する

ObjectCreateでラベルを作成しましょう。

ObjectCreate("Timer", OBJ_LABEL, 0, 0, 0);//オブジェクトを作成

ObjectSetでXY座標から25離れた場所にオブジェクトを設置させます。

ObjectSet("Timer", OBJPROP_XDISTANCE, 25);//オブジェクトのX座標
ObjectSet("Timer", OBJPROP_YDISTANCE, 25);//オブジェクトのY座標

チャートの四つ角にどこに配置するか設定しましょう。今回は左上なので0に設定します。

ObjectSet("Timer", OBJPROP_CORNER, 0);//チャートの隅を指定

オブジェクトの色を設定します。

ObjectSet("Timer",OBJPROP_COLOR,FontColor);//色の指定

EventSetTimer(1)で1秒ごとに動くように設定されています。

EventSetTimer(1);//一秒ごとに動くように設定

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

ObjectCreate("Timer", OBJ_LABEL, 0, 0, 0);//オブジェクトを作成
ObjectSet("Timer", OBJPROP_XDISTANCE, 25);//オブジェクトのX座標
ObjectSet("Timer", OBJPROP_YDISTANCE, 25);//オブジェクトのY座標
ObjectSet("Timer", OBJPROP_CORNER, 0);//チャートの隅を指定
ObjectSet("Timer",OBJPROP_COLOR,FontColor);//色の指定
EventSetTimer(1);//一秒ごとに動くように設定
Copy

※ObjectCreate/ObjectSetはMT4の初期からある書き方で、コンパイルは通りますが、公式には`ObjectCreate(0, 名前, 種類, …)`・`ObjectSetInteger`という新しい書き方が推奨されています。今回はシンプルさを優先して旧来の書き方のまま解説します。

OnDeinit()関数に記述する

OnDeinit()関数に記述しましょう。

OnDeinit()関数に記述することでインジケーターを消すと時間表示が消えます。

あわせて、EventSetTimer()で開始したタイマーは、インジケーターを外すときにEventKillTimer()で必ず停止させてください。呼び忘れると、意図しないタイミングでタイマーイベントが動き続ける原因になります。

EventKillTimer();//タイマーを停止
ObjectDelete("Timer");//インジケーター削除後に表示消す

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

void OnDeinit(const int reason)
  {
   EventKillTimer();//タイマーを停止
   ObjectDelete("Timer");//インジケーター削除後に表示消す
  }
Copy

OnTimer()関数に記述する

OnTimer()関数に記述しましょう。

OnTimer()関数はEventSetTimerで指定した秒数ごとに実行されます。

string MM,SS,OBJ;//文字列変数

TimeCurrent()関数とはサーバーの時間を表示する関数です。

XMなどの海外サーバーならその現地時刻ですし、日本にサーバーがあれば日本時間になります。

datetime ServerTime = TimeCurrent();//サーバー時間

Time[0]は、現在のローソク足の開始時間です。Time[0]をnowという変数に入れます。

datetime now = Time[0];//現在のローソク足の時間

Period()は時間足です。開いているチャートが5分足なら5ですし、15分なら15です。

now + Period()*60 – ServerTimeは「現在の時間+表示されている時間足*60-サーバー時間」です。

これによって残りの時間がわかります。

int Nokori = (int)(now + Period()*60 - ServerTime);//現在+表示されている時間足*60-サーバー時間

残りの時間を活用して

  • Hour:時間
  • Minute:分
  • Second:秒

の3つの変数に値を代入します。

int Hour = Nokori/3600;//時間足
int Minute = (Nokori/60)%60;//分足
int Second = Nokori - Minute*60 - Hour*3600;//秒足

もしMinuteが10以下だった場合は、デジタル時計のように01などのように表示させます。

int型のままでは数字表記なので、文字列に連結するために(string)でキャストします。

if(Minute<10)//分足が10より小さい
{
   MM = "0" + (string)Minute;//先頭に0を表示
}
else
{
   MM = (string)Minute;//string型に変換して代入
}

それをSecondでも同じように記載しています。

if(Second<10)//秒足が10より小さい
{
   SS = "0" + (string)Second;//先頭に0を表示
}
else
{
   SS = (string)Second;//string型に変換して代入
}

もし時間足が60以下だった場合は、分足と秒足のみを表示させて、

60以上だった場合は時間足と分足と秒足それぞれを表示させます。

if(Period()<=60)//表示されている時間足が60以下
{
   OBJ = MM + ":" + SS;//分足と秒足のみ
}
else
{
   OBJ = (string)Hour + ":" + MM + ":" + SS;//時間足と分足と秒足
}

最後にチャートに表示するために名前とOBJとフォントサイズを入れましょう。

ObjectSetText("Timer", OBJ, FontSize);//残り時間を表示

これでOnTimer()関数は完了です。

コピペしてコンパイルできない場合に確認すること

この記事のコードは、数値(int)と文字列(string)を連結する箇所すべてに(string)キャストを付けています。MQL4では「文字列 + 数値」の順番なら暗黙変換されますが、「数値 + 文字列」のように数値が先に来る書き方はエラーになることがあります。自分でアレンジする際も、数値を文字列とつなげる場合は必ず(string)でキャストしてから連結してください。

string MM,SS,OBJ;//文字列変数

datetime ServerTime = TimeCurrent();//サーバー時間
datetime now = Time[0];//現在のローソク足の時間
int Nokori = (int)(now + Period()*60 - ServerTime);//現在+表示されている時間足*60-サーバー時間

int Hour = Nokori/3600;//時間足
int Minute = (Nokori/60)%60;//分足
int Second = Nokori - Minute*60 - Hour*3600;//秒足
if(Minute<10)//分足が10より小さい
{
   MM = "0" + (string)Minute;//先頭に0を表示
}
else
{
   MM = (string)Minute;//string型に変換して代入
}
if(Second<10)//秒足が10より小さい
{
   SS = "0" + (string)Second;//先頭に0を表示
}
else
{
   SS = (string)Second;//string型に変換して代入
}

if(Period()<=60)//表示されている時間足が60以下
{
   OBJ = MM + ":" + SS;//分足と秒足のみ
}
else
{
   OBJ = (string)Hour + ":" + MM + ":" + SS;//時間足と分足と秒足
}
ObjectSetText("Timer", OBJ, FontSize);//残り時間を表示
Copy

コンパイルする

コンパイルしましょう。チャート上に残り時間が表示されていたら完成です。

MQL 残り時間表示 インジケーター 作成

1時間足に変えるとしっかりと表記が変わります。

MQL 残り時間表示 インジケーター 作成

ソースコード全体

Nokori-Timerのソースコード全体は以下に記載しています。

//+------------------------------------------------------------------+
//|                                                 Nokori-Timer.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

/*パラメーター*/
input int FontSize = 20;//フォントサイズ20
input color FontColor = clrYellow;//黄色
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   ObjectCreate("Timer", OBJ_LABEL, 0, 0, 0);//オブジェクトを作成
   ObjectSet("Timer", OBJPROP_XDISTANCE, 25);//オブジェクトのX座標
   ObjectSet("Timer", OBJPROP_YDISTANCE, 25);//オブジェクトのY座標
   ObjectSet("Timer", OBJPROP_CORNER, 0);//チャートの隅を指定
   ObjectSet("Timer",OBJPROP_COLOR,FontColor);//色の指定
   EventSetTimer(1);//一秒ごとに動くように設定
//---
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();//タイマーを停止
   ObjectDelete("Timer");//インジケーター削除後に表示消す
  }
//+------------------------------------------------------------------+
//| 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()
  {
//---
   string MM,SS,OBJ;//文字列変数

   datetime ServerTime = TimeCurrent();//サーバー時間
   datetime now = Time[0];//現在のローソク足の時間
   int Nokori = (int)(now + Period()*60 - ServerTime);//現在+表示されている時間足*60-サーバー時間

   int Hour = Nokori/3600;//時間足
   int Minute = (Nokori/60)%60;//分足
   int Second = Nokori - Minute*60 - Hour*3600;//秒足
   if(Minute<10)//分足が10より小さい
     {
      MM = "0" + (string)Minute;//先頭に0を表示
     }
   else
     {
      MM = (string)Minute;//string型に変換して代入
     }
   if(Second<10)//秒足が10より小さい
     {
      SS = "0" + (string)Second;//先頭に0を表示
     }
   else
     {
      SS = (string)Second;//string型に変換して代入
     }

   if(Period()<=60)//表示されている時間足が60以下
     {
      OBJ = MM + ":" + SS;//分足と秒足のみ
     }
   else
     {
      OBJ = (string)Hour + ":" + MM + ":" + SS;//時間足と分足と秒足
     }
   ObjectSetText("Timer", OBJ, FontSize);//残り時間を表示
  }
//+------------------------------------------------------------------+
Copy

まとめ

これで残り時間を表示させることができましたね。オブジェクトを活用することが徐々に慣れてきたと思います。

関連記事