【MQL4】GMTオフセット計算方法 (改善版)

MQL4 - How To Calculate GMT Offset お役立ち集
この記事は約5分で読めます。

MT4 EA開発で得られた ノウハウやお役立ち情報を時折書いていこうと思っています。

手始めに簡単なところから。

MQL4による”GMTオフセット”の計算方法のサンプルコードです。

GMTオフセットとは?

「GMTオフセット」もしくは「UTCオフセット」とは、タイムゾーンと協定世界時 (UTC) との時間差です。

  • 例えば、GMT+9である日本のGMTオフセットは「+9」になります。
  • この情報取得用のAPIはMQL4では用意されていないため、自分で算出する必要があります。
スポンサーリンク

【サンプルコード】

結論のソースコードから載せてしまいますが、Canaryは以下でGMTオフセットを取得しています。

/* ------------------------------------------------------------------
 * [Function] GMTオフセット取得API
 * ------------------------------------------------------------------ */
int GetGmtOffset() {
  //--- バックテスト時は固定値"3"を返却
  if (IsTesting()) { return 3; }

  //--- 「サーバ時刻(now)」と「GMT時刻(gmt)」を取得
  const datetime now = TimeCurrent();
  const datetime gmt = TimeGMT();

  //--- GMTオフセット値の計算
  const double offsetSeconds = double(now - gmt);
  return int(round(offsetSeconds / 3600.0));
}
Canary
Canary

括弧の位置やインデントがMT4のデフォルトと異なるのは、こだわりなのでご容赦w

他サイトでサンプルコードも見つけましたが、うまく行かないケースを発見~改善して、上記コードに落ち着きました。

  • 「日付またぎ は考慮されているが 月またぎ が考慮されていない」ようでした。

スポンサーリンク

【解説】

基本的に、TimeCurrent関数で取得したサーバ時刻(now) – TimeGMT関数で取得したGMT時刻(gmt) でオフセットを取得するだけなのですが、

MqlDateTime型をそのまま使って now.hour - gmt.hour のように時刻の数字だけ取り出して計算してしまうと、日付またぎ・月またぎも考慮が必要になってしまい面倒 です。

例えば、「now=”11/05 02:00″、gmt=”11/04 23:00″」のケースは差は3時間なので、GMTオフセットの期待値は「+3」です。

  • しかし、このケースは日付またぎなので、単純に now.hour - gmt.hour で計算すると「-21」になってしまい、+24する補正 が必要です。

さらに、日付またぎの判定は now.day - gmt.day だけでは月またぎ・年またぎのケースで問題が出るのでそれらの考慮も必要になりますが、上述した「他サイトのサンプルコード」ではこの考慮が抜けてました。

POINT

Canaryは、この now.hour - gmt.hour による補正は行わず、

StructToTime関数で時刻をエポック秒に変換してから引き算し、1時間で割る

ことでオフセット値を算出しました。※コードの14行目の「3600.0」が1時間に相当します。

また、13~14行目で

オフセット値をdoubleへキャスト→roundで四捨五入→intに再キャスト

しているのにも、ちゃんとした理由があります。(→下のコラム参照。)

「オフセット値をdoubleへキャスト→roundで四捨五入→intに再キャスト」している理由

当初は整数型 (int / long) で計算していましたが、そのままだと問題があったため、doubleを経由させるようにしました。目的は 秒単位誤差の丸め込み です。

【経緯】

  • nowとgmtはタイムゾーンが違うだけなので、分・秒単位は同値になるはず と考えていたが、実際は異なった
  • 「nowはサーバ由来」、「gmtはPC由来」と取得元が異なるためか、数秒の誤差が発生するケースがあった。(例:now=”12:00:00″、gmt=”9:00:04″)
  • 上記例で時間差は「2時間59分56秒」なのでGMTオフセットの期待値は「+3」だが、整数型で単純に処理すると (「59分56秒」は削られて)「+2」に計算されてしまった

【対策】

  • 他にも色々やり方はありますが、外部ライブラリを使わずに2行で完結できるのを重視し、 今回の「doubleへキャスト→roundで四捨五入→intに再キャストでの誤差丸め込み」を採用しました。
スポンサーリンク

【まとめ】

MQL4によるGMTオフセットの計算方法 をご紹介しました。

適宜コピー等して頂いて構いませんが、ご自分でも動作確認されることを推奨致します。

なお、本音としてはこう言った関数はMQL側で用意して頂けると!!ですw #MQL5もまだ対応してなさそう・・・

Canary
Canary

ちなみに、CanaryがGMTオフセットを計算するようになった経緯は、「約定通知Eメールに正確な時刻を載せるため」でした。ではでは~。

コメント

タイトルとURLをコピーしました