コンテンツにスキップ

【移植#70】1970年ダミー足をやめる — MT5履歴を指定日まで段階取得

EURUSDのH1チャート上でM1履歴の対象日時、最古日時、同期状態、最大バー数を照合したMT5画面

この記事の3行まとめ

  • 1970年のダミー足や履歴ファイル改変を使わず、MT5の標準時系列APIへ置き換えました
  • 1回500本ずつ古い側を要求し、対象日時を覆う確定足と同期状態を2回連続で確認します
  • 実機ではM1を10,000本確認し、対象日時を直前の確定足で覆ったことを独立検証しました

今回の原典は「1970年のダミー足で全期間更新を促す」方法

投稿日順で次に当たる2010年3月18日の記事は、MT4のHistory Centerへ1970年のダミーデータを追加し、チャートを更新する方法を紹介していました。

元記事「神速のHistorical Data ダウンロード術。」を読む

当時の狙いは、Homeキーで少しずつ古い履歴を受け取る代わりに、「1970年から現在までの不足分をまとめて要求する」ことです。完了確認には、チャートの最古日時やBarsの本数を使っていました。

一方で、原典には次の注意も書かれています。

  • ダウンロード後にダミーデータを削除する必要がある
  • 複数通貨を同時に取得すると、接続先へ大きな負荷を掛ける可能性がある
  • ダウンロード中は進捗を判定しにくい

この発想をMT5へ移すとき、ダミー足の作成や履歴ファイルの直接編集は再現しません。履歴へ偽の価格を混ぜず、必要な範囲だけを標準APIへ要求し、終了条件を数値で確認する形へ変えます。

移植#44との違い

移植#44でも、CopyRates()を使った履歴同期を扱いました。役割が重ならないよう、今回は対象軸を変えています。

対象 完了条件
移植#44 複数銘柄のM1を1件ずつ処理 各銘柄が指定本数へ到達
移植#70 1銘柄・1時間足を古い側へ遡る 指定日時を覆う実在バーを確認

「何本あるか」をそろえるのが#44、「この日時まで届いたか」を確かめるのが今回です。

古い側へ小分けで要求する

履歴要求には、MQL5公式のCopyRates()を使います。必要な時系列がまだ端末にない場合、インジケーターからの呼び出しはすぐに-1を返すことがありますが、その呼び出し自体がダウンロードや時系列構築の開始要求になります。

配布版は1秒タイマーで状態を読み直し、まだ対象日時へ届いていなければ、現在の最古バーより古い側を初期値500本ずつ要求します。

C++
const datetime request_from = series_first - PeriodSeconds(period);
const int copied =
   CopyRates(symbol, period, request_from, InpChunkBars, rates);

一度に全期間を配列へ入れず、1回の上限を固定しています。Sleep()でインジケーターの処理を止めるのではなく、タイマーイベントをまたいで端末側の同期を待ちます。

対象日時がすでに履歴内なら、その日時以前のバーを1本だけ読み返します。

C++
const int shift = iBarShift(symbol, period, effective_target, false);
const datetime covered_bar = iTime(symbol, period, shift);

exact=falseなので、週末や取引休止時間を指定しても、対象日時以前で最も近い実在バーを探せます。今回の検証でも対象は日曜日でしたが、直前の金曜日のM1足を取得できました。

3種類の「最古日時」を分けて表示する

履歴状態は、公式のSeriesInfoInteger()から読みます。

表示 意味
SERVER FIRST サーバーが示す、その銘柄全体の最古日時
TERMINAL FIRST 端末に保存された、その銘柄全体の最古日時
SERIES FIRST 現在構築されている銘柄・時間足の最古日時
COVERED BAR 指定日時以前で最も近い、実際に読めたバー

SERVER FIRSTが古いからといって、その日から現在まで全時間足のデータが連続しているとは限りません。配布版が合格に使うのは、対象時間足のCOVERED BARSERIES_SYNCHRONIZEDCopyRates()の実読出し結果です。

対象日時がサーバー最古日時より古い場合は、要求不能な日付を永久に追わず、サーバー最古日時を実効目標にします。要求した日時と実効目標は別々に表示するため、丸めたことも画面で分かります。

最大バー数と再試行上限で必ず止める

公式の時系列データ取得の解説では、履歴を古い側へ要求するときにTERMINAL_MAXBARSを確認する例が示されています。

配布版も、次のどちらかへ到達したら成功扱いにせず停止します。

  • 端末の最大バー数へ達しても対象日時を覆えない
  • 最大試行回数へ達しても同期・読出し条件がそろわない

前者はTERMINAL MAX-BARS LIMIT REACHED、後者はFAILED AFTER RETRY LIMITです。接続切れ、業者側の履歴不足、端末設定の不足を「まだ処理中」として無期限に隠しません。

ダウンロード

70_History_Range_Backfill_Monitor_v1_00.mq5 をダウンロード

MT5のIndicatorsへ保存してコンパイルし、対象と異なる時間足のチャートへ適用してください。初期設定では、装着チャートと同じ銘柄のM1履歴を5日前まで確認します。たとえばEURUSD H1へ装着すれば、EURUSD M1が対象です。

同じ銘柄・同じ時間足へ装着すると初期化を拒否します。公式資料でも、インジケーター自身と同じ銘柄・時間足の履歴更新を要求することは、同じスレッドで履歴更新と計算が競合するため望ましくないと説明されています。

主なパラメーター

パラメーター 初期値 役割
InpTargetSymbol 空欄 対象銘柄。空欄は装着チャートと同じ銘柄
InpTargetPeriod M1 取得・確認する時間足
InpStartDate 0 固定の対象日時。0ならInpDaysBackを使用
InpDaysBack 5 装着時点から遡る日数
InpChunkBars 500 1回に要求する最大バー数
InpStableChecks 2 成功条件を連続確認する回数
InpMaxAttempts 60 最大試行回数
InpShowPanel true 状態パネルの表示

専用MT5で実機検証

配布インジケーターと独立検証EAを、専用MT5へ配置してコンパイル・実行しました。

コンパイル結果

対象 エラー 警告
配布インジケーター 0 0
独立検証EA 0 0

実行条件

項目
MT5 Build 6140
装着チャート EURUSD H1
対象履歴 EURUSD M1
対象日時 2026-08-30 12:13
1回の要求上限 500本
安定確認 2回
端末の最大バー数 10,000本

実測結果

確認項目 結果
M1バー数 10,000本
M1系列の最古日時 2026-08-26 13:29
対象日時を覆うバー 2026-08-28 23:54
サーバー最古日時 1971-01-04 00:00
端末最古日時 2018-08-24 00:00
同期状態 YES
履歴要求 2回
最終読出し 1本
安定確認 2/2

独立検証EAは、配布版が公開する17個の計算バッファを17/17取得しました。そのうえで、SERIES_BARS_COUNT、3種類の最古日時、同期状態、最大バー数、iBarShift()iTime()による対象バーを別に読み直し、すべて一致することを確認しています。画面を構成する11個のオブジェクトも11/11一致しました。

検証環境には対象日時より古いM1履歴がすでにありました。そのため、今回の2回は新規ダウンロード量を測った値ではなく、対象バーを実際に読み出し、同じ条件が2回連続で成立した回数です。空の端末で何本ダウンロードできるか、別業者でも同じ日時まで取得できるかまでは、この結果から断定しません。

検証中に注文やポジションの操作は行っていません。

使えないこと・注意点

  • サーバーに存在しない履歴を作り出すことはできません。
  • 最古日時を確認しても、途中の全バーが欠損なしとは限りません。
  • 端末の最大バー数より古い目標は、設定を見直さない限り到達できない場合があります。
  • インジケーターからの初回要求は-1になることがあります。すぐ失敗とせず、パネルの再試行を確認してください。
  • 初期値の5日前は固定日ではなく、インジケーターを装着した時点から計算します。
  • Tick履歴ではなく、指定時間足のバー履歴が対象です。
  • 対象銘柄はMarket Watchへ追加しますが、終了時に自動削除しません。
  • 大きなチャンクや長い期間を指定すると、通信・メモリ・ディスク負荷が増えます。
  • 売買処理はなく、履歴取得が取引成績を改善することを示すものではありません。

まとめ

1970年のダミー足は、「必要な開始日時を端末へ伝える入口」が乏しかったMT4時代の工夫でした。MT5では、偽のバーを混ぜなくても、標準の時系列APIから必要範囲を要求できます。

大切なのは、要求を投げたことではなく、対象日時以前の実在バーを読み出せたか、系列が同期しているか、端末の上限へ突き当たっていないかを分けて確認することです。小分けの要求、連続確認、明示的な停止条件をそろえることで、速さだけでなく結果まで追える履歴取得に変えられます。

前: 【移植#69】アンディの雲が入れ替わる位置へ縦線 — 26本先の表示時刻まで照合する

次: 【移植#71】偽Tickを送らない — MT5タイマーの周期と取りこぼしを測る

— SPONSORED —