【移植#95】履歴を読み直してもローソクを重ねない — 時刻キーと所有範囲で再同期¶

この記事の3行まとめ
- 履歴が後から追加されたり、途中の欠損が補われたりすると、MT5は
prev_calculatedを0に戻します - 描画名をバー時刻から作り、全再計算時には自分の名前の範囲だけ消して再描画します
- 専用MT5で全再構築後も表示数が安定し、別オブジェクトが保護されることを確認しました。実際の履歴追加操作は自動検査で再現していません
元記事の問題は、履歴が増えたときの重ね描き¶
2010年5月9日の元記事では、MT4のCustomCandleがHomeキーで過去へ移動した際、追加されたバーのローソクオブジェクトを重ねて作る問題を扱っていました。バーは右端へ足されるだけとは限らず、過去側や履歴の途中に後から加わることがあります。元記事ではIndicatorCounted()が0になる状況でインジケーターを初期化し直していました。
元記事「CustomCandle.mq4 の不具合修正」を読む
今回はMT4の再初期化コードをそのまま移すのではなく、MT5の再計算通知とオブジェクトの命名を使って、同じ時刻のバーを二重に作らない形へ置き換えます。
MT5は履歴変更をprev_calculated=0で知らせる¶
MT5の公式リファレンスによると、より深い履歴が読み込まれた場合や、履歴の欠損が埋められた場合、端末はOnCalculate()へ渡すprev_calculatedを0にします。OnCalculateの公式リファレンス
この通知を受けたら、過去に計算した位置をそのまま信用せず、表示対象を作り直す必要があります。一方、普段のティックごとにすべての過去バーを描き直す必要はありません。
バー時刻をキーにして、自分のオブジェクトだけ管理する¶
配布インジケーターは、ローソク1本につきヒゲと実体の2オブジェクトを使います。名前にはチャートID、インスタンスID、バーの開始時刻を含めます。同じ時刻をもう一度処理しても新しい名前は増えず、既存オブジェクトの座標と色が更新されます。
履歴の全再計算時には、自分の描画用接頭辞に一致するオブジェクトだけを削除し、最大300本を作り直します。ObjectsDeleteAll()は名前の接頭辞を指定できますが、先行するチャート処理の完了を待つ同期関数でもあります。そのため削除を毎ティックには行わず、履歴リセット時に限定します。ObjectsDeleteAllの公式リファレンス
通常ティックは最新足だけを更新し、新しいバーができたときに変化した足を追加します。バー時刻を名前にすることで、チャート内の位置がずれても同じバーを識別できます。インスタンスIDが重複した場合は、既存の描画を上書きしないよう起動を拒否します。
実機では描画数と所有範囲を確認¶
専用MT5でEURUSD H1へ適用し、ローソクが2オブジェクトずつ、所有マーカーが1個だけ作られることを確認します。さらに検証EAから専用イベントを送り、履歴リセットと同じ全再構築分岐を強制した後、描画数が変わらないことを確認します。無関係な水平線が稼働中と終了時の両方で残ることも検査します。スクリーンショットはMT5から直接取得しました。
この自動検査は、起動後と全再構築後のオブジェクト数が増えないこと、所有接頭辞が分離されていることを確認します。履歴の追加・欠損補完を実際に発生させるUI操作までは再現していないため、その場面での端末固有の通知発生を実測したとは述べません。コードでは公式通知に従い、prev_calculated==0で同じ再構築処理を実行します。
ダウンロード¶
95_CustomCandle_History_Sync_v1_00.mq5 をダウンロード
適用すると、通常のローソク足チャートへ直近のカスタムローソクが重なります。色と本数は入力で変更できます。カスタム表示を比較するときは、標準ローソクとの重なりが読み取りにくくならないよう、チャートの標準足を非表示にするか、色を分けてください。
前後の記事¶
前: 【移植#94】日足ATR(1)でボラティリティを比較する
次: 【移植#96】2つのグリコ戦略を1万回比べる — 乱数と期待値を分けて読む
あわせて読みたい記事¶
- 【移植#53】Delete→Undoをやめる — 選択中オブジェクトを安全に読む
- 【移植#58】QQE-VTをMT5へ — RSI平滑線とクロスをサブウィンドウで確認する
- 【移植#74】再初期化しても同じ形か — 差分計算と全計算を500本照合