【移植#54】キー送信をやめる — 複数チャートの時間足をMQL5で一括変更¶

この記事の3行まとめ
- DLL、キー送信、外部常駐ツールを使わず、MT5のチャート操作APIだけで時間足をそろえます
ChartSetSymbolPeriod()のtrueを完了扱いせず、変更後に全チャートの時間足を再読します- 専用MT5ではM1・M5・M15・D1の4チャートをH4へ変更し、4/4一致と売買状態不変を確認しました
今回の原典は「6画面をワンクリックで切り替えたい」¶
投稿日順で先に当たる2010年2月24日の記事は、M1履歴の欠損とバックテスト用ティックを扱っていました。ただし、その中心テーマはすでに【移植#36】バックテスト履歴の証拠を点検するで、履歴品質、ギャップ、ティックモードまで実装検証しています。
同じ内容を番号だけ変えて繰り返さず、今回は次の2記事を一組で扱います。
- 2010年2月25日: 元記事「(続)複数のチャートの時間足を一括変更するスクリプト。」
- 2010年2月26日: 元記事「(続々)複数のチャートの時間足を一括変更するスクリプト。」
質問者の希望は、複数通貨を6分割表示しているとき、全画面をM5からH1、あるいはD1へ一度に切り替えることでした。
最初の案は、開いているMT4ウィンドウを数え、それぞれへ時間足変更のメッセージを送るスクリプトです。しかし、スクリプト自身が動くチャートを変更しようとすると停止確認が出て、その1枚だけ変更できない問題が残りました。
翌日の案では、AutoHotKey系の外部ツールへ作り直し、ショートカットキーから一括操作していました。当時の制約を越える実用的な工夫ですが、現在のMT5へそのまま持ち込む必要はありません。
- アクティブウィンドウへ依存する
- キー割り当ての競合が起きる
- DLLや外部実行ファイルの許可が必要になる
- コマンドを送った後、本当に全チャートが変わったか分からない
- 操作元チャートのプログラムが停止・再初期化される
今回残すのは「複数チャートを一操作でそろえる」という目的です。キー入力の再現は捨て、MQL5の標準APIへ置き換えます。
MT5では開いているチャートをIDで列挙できる¶
最初のチャートIDはChartFirst()、次のIDはChartNext()で取得できます。
配布版は変更処理へ入る前に、対象チャートのID、通貨、現在の時間足を配列へ保存します。
long chart_id = ChartFirst();
while(chart_id >= 0)
{
// chart_id、ChartSymbol(chart_id)、
// ChartPeriod(chart_id)を先に保存
chart_id = ChartNext(chart_id);
}
列挙しながら変更するのではなく、最初に対象を固定するのがポイントです。処理途中で操作元の時間足が変わると、チャート上のプログラムが再初期化されるからです。
初期設定では、1回の対象を32枚までに制限します。上限を超えた場合は、先頭32枚だけを黙って変えません。TRUNCATED: YESとして、変更開始前にバッチ全体を失敗させます。
ChartSetSymbolPeriodのtrueは「完了」ではない¶
時間足の変更にはChartSetSymbolPeriod()を使います。
この関数は非同期です。trueが意味するのは、変更コマンドを対象チャートのキューへ追加できたことです。H4の描画まで終わった、あるいはインジケーターの再計算まで終わったという意味ではありません。
そこで配布版は、次の二段階で判定します。
- 対象チャートごとに変更コマンドをキューへ追加する
- 1秒間隔で全対象の
ChartPeriod()を再読する
指定時間内に、対象数と再列挙数が一致し、すべての時間足が目標値になり、キュー追加失敗も0件だった場合だけPASSです。
チャートが閉じられた、別のチャートが対象へ追加された、時間足が戻された、といった場合は件数または時間足が一致しません。見た目がたまたまH4に見える1枚だけで、バッチ全体を合格にはしません。
操作用チャートは初期設定で保護する¶
MetaQuotesのMQL5 AlgoBookでは、通貨または時間足の変更によって、チャート上のEAが再初期化され、実行中のスクリプトはアンロードされると説明されています。
そのため、配布版のInpIncludeControllerChartは初期値falseです。
たとえば、6通貨の監視チャートとは別に操作用チャートを1枚置き、そこへこのコントローラーを適用します。M1、M5、M15、H1、H4、D1のボタンを押すと、操作用以外のチャートが対象になります。
厳密に操作用を含む全チャートを変えたい場合はtrueにできます。その場合は操作元を最後に変更し、チャート上の非表示オブジェクトへバッチ状態を保存してから再読を続けます。ただし、そのチャート上で動くEAやスクリプトにも再初期化・停止の影響があるため、通常は操作用を分ける方が安全です。
6つのボタンと状態表示¶
配布インジケーターには、次の時間足ボタンがあります。
| ボタン | 変更先 |
|---|---|
M1 | 1分足 |
M5 | 5分足 |
M15 | 15分足 |
H1 | 1時間足 |
H4 | 4時間足 |
D1 | 日足 |
画面左上には、次の状態を表示します。
- 目標時間足と
READY/VERIFYING/PASS/FAIL - 対象数、キュー追加数、すでに目標だった数
- 再読一致数、未一致数、確認回数
- キュー追加失敗、上限打切り、最後のエラー
- 操作用チャートと対象範囲
- 対象先頭4枚の通貨、現在時間足、一致状態
InpChartIdsCsvは、対象を特定のチャートIDだけに制限する上級者向け入力です。空欄なら、初期設定では操作用を除く開いている全チャートが対象になります。
12本の診断バッファを独立照合した¶
画面の文字だけを見て合格にはしていません。配布版は次の12本を計算用バッファとして公開します。
| # | 診断値 |
|---|---|
| 1 | バッチ状態(失敗/待機/確認中/合格) |
| 2 | 目標時間足 |
| 3 | 対象チャート数 |
| 4 | キューへ追加できた数 |
| 5 | キュー追加失敗数 |
| 6 | 変更後の再読一致数 |
| 7 | 未一致数 |
| 8 | 変更不要だった数 |
| 9 | 再読回数 |
| 10 | 再列挙できた対象数 |
| 11 | 上限打切り |
| 12 | 最後のエラー |
専用の検証EAは、操作用EURUSD・H1とは別に4枚を開きました。
| 通貨 | 変更前 | 変更後 |
|---|---|---|
| GBPUSD | M1 | H4 |
| USDJPY | M5 | H4 |
| AUDUSD | M15 | H4 |
| NZDUSD | D1 | H4 |
検証EAは配布版の集計関数を再利用せず、保持していた4つのチャートIDへChartSymbol()とChartPeriod()を直接実行し、通貨が変わっていないことと、4枚すべてがH4になったことを照合しました。
実行条件¶
| 項目 | 値 |
|---|---|
| MetaTrader 5 | Build 6061 |
| 操作用チャート | EURUSD・H1 |
| 対象チャート | 4枚 |
| 目標時間足 | H4 |
| 確認間隔 | 1秒 |
| 確認タイムアウト | 10秒 |
| DLL・外部キー送信 | なし |
| 売買許可 | なし |
検証結果¶
| 確認項目 | 結果 |
|---|---|
| 配布インジケーターのコンパイル | 0エラー・0警告 |
| 独立検証EAのコンパイル | 0エラー・0警告 |
| 対象数 | 4 |
| キュー追加 | 4 |
| キュー追加失敗 | 0 |
| 変更不要 | 0 |
| H4再読一致 | 4 / 4 |
| 上限打切り | なし |
| 最後のエラー | 0 |
| 注文・ポジション変更 | なし |
| 実画面キャプチャー | 成功 |
ダウンロードと使い方¶
54_Multi_Chart_Timeframe_Controller_v1_00.mq5 をダウンロード
- ファイルをMT5のカスタムインジケーターフォルダーへ保存します
- MetaEditorでコンパイルします
- 時間足を変えない操作用チャートへ適用します
- M1、M5、M15、H1、H4、D1のいずれかを押します
VERIFIEDが対象数と一致し、STATUS: PASSになることを確認します
主な入力値は次のとおりです。
| パラメーター | 初期値 | 役割 |
|---|---|---|
InpMaxCharts | 32 | 1バッチの最大対象数 |
InpVerifyTimeoutSec | 10 | 変更後の再読待ち時間 |
InpShowPanel | true | ボタンと状態表示 |
InpIncludeControllerChart | false | 操作用チャートも変更するか |
InpChartIdsCsv | 空欄 | 空欄なら対象範囲の全チャート |
使えないこと・注意点¶
- 時間足を変えたチャート上のEAは再初期化されます。EAの内部状態が正しく復元されるかは、そのEA側の責任です。
- 実行中のスクリプトがあるチャートを変更すると、スクリプトはアンロードされます。
PASSは時間足の再読一致です。各チャートのインジケーター計算完了や履歴同期完了までは保証しません。- 検証中に対象チャートを開閉すると、件数不一致で失敗する場合があります。
InpMaxChartsを超えた場合は一部だけを変更せず、開始前に失敗します。- ボタンはM1、M5、M15、H1、H4、D1の6種類です。他の標準時間足を追加する場合はコード変更が必要です。
- 通貨、テンプレート、プロファイル、チャート配置は変更しません。
- 注文、取消、ポジション管理、自動売買は行いません。
ロジック評価の結論¶
原典の価値は、6枚のチャートを一つずつ操作する反復作業を、1回の入力へまとめたことです。
現在のMT5では、外部ツールでキーを再現しなくても、開いているチャートをIDで列挙し、標準APIで時間足を変更できます。ただし、APIへ置き換えるだけでは不十分でした。
- 対象を変更前に固定する
- 操作用チャートを既定で保護する
- 対象数に上限を設ける
- 非同期のキュー追加と変更完了を分ける
- 変更後に通貨と時間足を再読する
- 一部成功を全体成功と呼ばない
専用MT5では、異なる4つの時間足をH4へそろえ、4件すべてを独立に再読できました。
ワンクリックの便利さは残し、キー送信への依存と「たぶん変わった」という曖昧さを捨てる。これが今回のMQL5移植です。
前後の記事¶
前: 【移植#53】Delete→Undoをやめる — 選択中オブジェクトを安全に読む
次: 【移植#55】古いsymbols.sel改変をやめる — 固定スプレッドのカスタム銘柄をMQL5で作る