今回は、チャート上に残り時間を表示するインジケーターを作成していきたいと思います。
チャート上に残り時間を表示するインジケーター
今回は、チャート上に残り時間を表示するインジケーターを作成していきたいと思います。
メタエディタ(MetaEditor)を立ち上げる
メタエディタ(MetaEditor)を立ち上げましょう。今回は名前を「Nokori-Timer」で作成します。
パラメーターを記述する
パラメーターを記述しましょう。オブジェクトのフォントサイズと色を決めます。
input int FontSize = 20;//フォントサイズ20 input color FontColor = clrYellow;//黄色
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);//一秒ごとに動くように設定
※ObjectCreate/ObjectSetはMT4の初期からある書き方で、コンパイルは通りますが、公式には`ObjectCreate(0, 名前, 種類, …)`・`ObjectSetInteger`という新しい書き方が推奨されています。今回はシンプルさを優先して旧来の書き方のまま解説します。
OnDeinit()関数に記述する
OnDeinit()関数に記述しましょう。
OnDeinit()関数に記述することでインジケーターを消すと時間表示が消えます。
あわせて、EventSetTimer()で開始したタイマーは、インジケーターを外すときにEventKillTimer()で必ず停止させてください。呼び忘れると、意図しないタイミングでタイマーイベントが動き続ける原因になります。
EventKillTimer();//タイマーを停止
ObjectDelete("Timer");//インジケーター削除後に表示消す
これでOnDeinit()関数の記述は完了です。
void OnDeinit(const int reason)
{
EventKillTimer();//タイマーを停止
ObjectDelete("Timer");//インジケーター削除後に表示消す
}
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);//残り時間を表示
コンパイルする
コンパイルしましょう。チャート上に残り時間が表示されていたら完成です。

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

ソースコード全体
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);//残り時間を表示
}
//+------------------------------------------------------------------+
まとめ
これで残り時間を表示させることができましたね。オブジェクトを活用することが徐々に慣れてきたと思います。
コメント