コンテンツにスキップ

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

MT5のEURUSD H1チャートに直近80本の青と赤のカスタムローソクを重ねた画面

この記事の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万回比べる — 乱数と期待値を分けて読む

あわせて読みたい記事

— SPONSORED —