——————————————————————————————-
前回の講座記事では「新しいバーのオープンのみに注文を発注できるクラス」の実装について解説しました。
まず今回のクラスを作るにあたり、「そもそも日時データとは何?」「確定足って何?」という部分のおさらいをしました。
※詳しくは前回記事の「はじめに:時間及び日付データに関して」セクション及び「確定足についてのおさらい」「新しいバーオープンでの取引についての前提」セクションをご覧ください。
そして、「新しいバーのオープンのみに注文を発注できるクラス」すなわち、OriginalCNewBarクラスの実装手順を解説していきました。
※実装手順については前回記事の『「新しいバーのオープンのみに注文を発注できるクラス」実装の為のロードマップ』セクションをご覧ください。
各工程への内部リンクを貼っているのでそこから見たい手順を辿る事ができます。
前回の記事にて、
OriginalCNewBarクラスに追加したメンバは以下の通りです。
・配列「TimeArray」:現在のバーの時間が時系列で格納される事を想定した配列
・変数「LastTimeVar」:直近にチェックした時間が格納される事を想定した変数
・OriginalCNewBar関数:配列「TimeArray」に時系列セットを施すコンストラクタ
・CheckNewBar関数:新しいバーがオープンした瞬間かどうかをチェックする処理を担う関数
※CheckNewBar関数の処理実装記述については「CheckNewBar関数の処理実装記述について」セクションをご覧ください。
そして最後に、作ったOriginalCNewBarクラスをメインプログラムでどのように使っていくか?という簡単な一例を紹介しました。
※詳細は前回記事の「メインプログラムで今回作ったクラス・関数をどのように使っていくかを確認する」セクションをご覧ください。
——————————————————————
今回も日時データの扱いについてです。
今回はEAを作る際に、datetime型の情報をどうやって落とし込んでいくか?という事について基本的な考え方を解説していきたいと思います。
今回の記事を読めば、datetime型についての復習になる事はもちろん、EAに時間指定操作の機能を実装するための基本が理解できるように構成してありますので、是非今回も楽しんで読んでいただければと思います。
はじめに:そもそもdatetime型は1970年1月1日午前0時からの経過秒数で表されている
MQL5 EA講座 第16回「データ型その6 datetime型」
にて初めて紹介したdatetime型、日時データを格納できるデータ型であるという事はご理解頂いているかと思うのですが、このdatetime型、具体的にどのような形でデータが保存されているかというと、見出しにも書いた通り、
1970年1月1日午前0時からの経過秒数で表されていた形で格納されています。
この、1970年1月1日の真夜中(世界協定時刻)からの総秒数で日時情報を表す形式をUNIXタイムと言います。
※UNIXタイムについては別途解説記事を書いていますので、詳細は↓の記事をご参照ください
従って、本来datetime型の数字は人間が直接「日時情報」として読み取るには理解しにくい巨大な値となっています。
例えば「2024年3月12日03:00」というデータがdatetime型の変数に格納されている時、この値をUNIXタイムにすると「171029880」という値になります
しかし、MT5ターミナルへのログ出力等において、datetime型の値は自動的に読みやすい日付と時刻の形式(例:yyyy.mm.dd hh:mi
)の文字列に変換されて表示されます。
この仕様により、開発者やトレーダーがログを読んだり、データを解析したりする際に日付と時刻を容易に理解できるようになっています。
datetime型は日付データの比較を始めとする数学的な操作が簡単なのがメリット
この、1970年1月1日午前0時からの経過秒数で表されるUNIXタイム形式表示、すなわちdatetime型のメリットは
コンピュータが数学的に操作する事が簡単になる点です。
例えば2つのdatetime型の日時情報があったとします。
1つ目の日時情報は2024年3月12日03:00
2つ目の日時情報は2024年3月14日22:00
上記のケース、我々人間がこの情報を理解しようとすれば、その文字情報から2024年3月12日03:00の方が2024年3月14日22:00よりも時系列的に早い日時であることは容易にくみ取れるわけですが、コンピュータの場合はそうはいきません。
文字列情報からどちらの日時情報が時系列的に早い日時であるかという事を判断する能力をコンピュータは持ち合わせていません。
その一方で、UNIXタイム形式であれば、重ね重ね書いているように1970年1月1日午前0時からの経過秒数である訳ですから、その二つの数字を数学的な大小で比較すればどちらの日時データが時系列的に早いかは一目瞭然となります。
// スクリプトの開始時に実行される関数
void OnStart()
{
// datetime型の変数date1に特定の日時を設定
datetime date1=D'2024.03.12 03:00';
// datetime型の変数date2に特定の別の日時を設定
datetime date2=D'2024.03.14 22:00';
// date1がdate2よりも前の日時であれば、以下の処理を行う
if(date1 < date2)
{
// date1が早い日時であることをコンソールに出力
Print("date1はdate2よりも早いです"); // true
}
// それ以外の場合、つまりdate1がdate2よりも後の日時であれば、以下の処理を行う
else if(date1 > date2)
{
// date2が早い日時であることをコンソールに出力
Print("date2はdate1よりも早いです");
}
}// void OnStart()
上記のサンプルコードでは「2024年3月12日03:00」という文字列情報を、datetime型に変更した変数「date1」と「2024年3月12日03:00」文字列情報を、datetime型に変更した変数「date2」との比較を関係演算子を用いて行い、その結果をログ出力させたものになります。
サンプルコードの結果は言うまでもなく、
“date1はdate2よりも早いです”
がログ出力されます。
datetime型の値に「1日」「1時間」といった期間を足したり引いたりしたい場合
日時情報をdatetime型で扱う事のもう一つのメリットは、例えば「1日後」や「1時間前」といった、特定の日時から任意の期間より前(あるいは後)の時間を導き出したい時、単に「1日後」や「1時間前」を秒数に換算した値を日時情報に足したり引いたりすれば、簡単に求まる事です。
例えば、1時間は秒換算すると3,600秒、
1日は秒換算すると86,400秒、
1年(閏年を考慮せず365日として)は秒換算すると31,536,000秒になります。
「datetime型は日付データの比較を始めとする数学的な操作が簡単なのがメリット」セクションで書いたサンプルコードに再び目を向けてみましょう
変数「date1」に格納されている「2024年3月12日03:00」という日時情報の1日後の日付を求めたいのであれば↓
//date1に1日(24時間)を足す
datetime add_Day=date1+86400;//2024.03.13 03:00が出力される
単純に変数「date1」に86400秒を足し合わせた値を変数「add_Day」に代入すればよいだけです。
出力結果は必然的に2024.03.13 03:00という事になります。
※計算に関するMQL5の記述については↓の記事群をご参照ください
・第32回「関係演算子(Relation Operations)」
datetime型の値を文字列情報に変換したい時は、TimeToString関数を使う
EAの開発過程において、datetime型の値を文字列情報に変換したい時は、TimeToString関数を使います。
この記事の「はじめに:そもそもdatetime型は1970年1月1日午前0時からの経過秒数で表されている」セクション最後に書いたように、MT5へのログ出力において、datetime型の値は自動的に読みやすい日付と時刻の形式(例:yyyy.mm.dd hh:mi
)の文字列に変換されて表示される仕様にはなっています。
ただし、例えば」外部ファイルに日時データを出力したり、外部システムへの日時データの送信などといったMT5仕様の範囲外におけるdatetime型→文字列への変換が必要な局面がある際TimeToString関数関数で明示的な型変換をする、という事になります。
※型変換(タイプキャスト)については↓の記事をご参照ください
TimeToString関数は時刻を表す数字(UNIXタイム)を、私たちが普段使う日時の形式の文字列に変換するために使われます。
第1引数に、文字列に変換したいdatetime型の日時情報を記述します。
// datetime型の変数date2を文字列に変換
string TtoS= TimeToString(date2);
// 変換した文字列を表示
Print(TtoS);
出力結果は「2024.03.14 22:00:00」となります。
※TimeToString関数については別途記事にしていますので↓のリンクをご参照ください
StringToTime関数を使って文字列からdatetime型の日時情報に変換することも可能
TimeToString関数とは反対に、StringToTime関数は「yyyy(西暦年).mm(月).dd(日).hh(時):mm(分):ss(秒)」という形式で記述された文字列データをdatetime型の日時情報に変換できる関数です。
例えば、2024.03.14 22:00という文字列をdatetime型の日時情報にに変換したい場合、StringToTime関数に以下のような書式で文字列を渡します↓
// 日付と時間の文字列を 'datetime' 型に変換
string dtConst = "2024.03.14 22:00"; // 文字列定数で日付と時間を定義
datetime dtDate = StringToTime(dtConst); // 文字列を 'datetime' 型に変換
上記のサンプルコードではStringToTime関数を使って、"yyyy.mm.dd hh:mi"
形式の文字列を datetime型に変換しています。
これにより、日付と時刻を扱う際の計算や比較などが可能になりました。
※StringToTime関数についても別途記事にしていますので詳細は↓の記事をご参照ください
文字列をシングルクォーテーションで囲み、その前に大文字のDを付けることで、datetime定数を作成することもできる
これから書く事は、すでに第16回「データ型その6 datetime型」ですでに解説した事でもありますが、おさらいの為に改めて書いておきます。
MQL5では、文字列をシングルクォーテーションで囲み、その前に大文字のDを付けることで、datetime型の定数を作成することもできます↓
void OnStart()
{
//変数「varDate」に2022年6月23日午前6時というデータを代入する
datetime varDate=D'2024.03.15 06:00:00';
//コメント出力をする
Comment(varDate);
}
- 大文字アルファベットの「D」を書く。
- 年、月、日の順に、ピリオドで区切る形で記述する。
- 日の後に、半角スペースを開けてから時間、分、秒の順にコロンで区切る形で記述する。
- 大文字アルファベットのD以降の記述内容をシングルクォーテーション(‘)で挟む
以上の手順を踏むことによって
日付・日時データをdatetime型の変数に格納することができます。
今回の記事で新たにお伝えした方法と、おさらいにとなる上記の方法を使えばより柔軟にdatetime型の情報を操作できるようになるでしょう。
日時情報の取り扱いについてはMqlDateTime構造体という便利な構造体があるのですが、MqlDateTime構造体については次回取り上げたいと思います。
まとめ
今回の講座記事ではdatetime型を使って、日時データを操作する時の基本的な考え方についてお話しました。
datetime型、およびUNIXタイムの原理原則を改めてお伝えし、その特性を生かして2つの日時データを比較したり、「1日」「1時間」といった特定の期間を足したりすることによって、特定の日時情報を取得する方法を解説しました。
そして、datetime型と文字列型との型変換を行える関数として、TimeToString関数とStringToTime関数の使い方を紹介しました。
最後に復習も兼ねて、文字列をシングルクォーテーションで囲み、その前に大文字のDを付けることで、datetime型の定数を作成する、という講座記事第16回で解説した内容を改めて紹介しました。
今回紹介した時間情報の操作方法に加え、次回解説するMqlDateTime構造体を理解した後は、タイムスタンプを操作するクラスを作っていく予定です。
今回は一旦以上とさせていただきます。
最後までお読みいただきありがとうございました。
第115回「チャート上に新しいバーが生成される瞬間にのみ注文できるクラスを作る」←