【移植#29】複数のMT5で状態ファイルを共有する — FILE_COMMONで安全に受け渡す¶

この記事の3行まとめ
- 複数のMT5で実行時データを共有するなら、まずMQL5標準の
FILE_COMMONを使います - 共有するのは小さな状態ファイルだけに絞り、端末設定やMQL5フォルダ全体は結合しません
- 専用MT5で2ノード分を検出し、共通ファイルの再読込と有効期限判定まで確認しました
今回の原典は「複数MT4のフォルダ同期」¶
投稿日順で次に当たる2010年1月16日の記事では、複数のMT4を使うときにexpertsフォルダをWindowsのジャンクションで共有する方法が紹介されていました。
元記事「複数の MT4 で、experts フォルダを共有する。」を読む
別々の端末へ同じファイルを何度もコピーすると、「片方だけ古い」という事故が起きます。1つの実体を複数の場所から参照するという原典の発想は、現在でもよく分かります。
一方、MT5ではプログラム、設定、履歴、ログがデータフォルダ内で明確に分かれています。公式ヘルプでも、複数のプラットフォームを同時に動かす場合は別々のインストール先を使い、各端末のデータフォルダは「ファイル」→「データフォルダを開く」から確認する構成です。
そこで今回は、フォルダ全体を同一化するのではなく、端末間で本当に受け渡したい小さな実行時データだけを共有します。
ジャンクションをそのまま使わない理由¶
Windowsのmklink /Jは現在もディレクトリジャンクションを作れる標準機能です。リンク側で行った変更は実体側へ反映されるため、リンク側でファイルを消せば実体からも消えます。
これは便利ですが、MT5のデータフォルダ全体を結合すると共有範囲が広すぎます。
| 対象 | 今回の判断 | 理由 |
|---|---|---|
| 端末設定・口座情報 | 共有しない | 端末ごとに分離したい情報です |
| 履歴・ログ・テスター | 共有しない | 同時書き込みや肥大化の影響を避けます |
.mq5 / .ex5一式 | 自動では共有しない | 更新・コンパイル単位を端末ごとに確認できます |
| 小さな状態ファイル | FILE_COMMONで共有 | MQL5のファイルサンドボックス内で範囲を限定できます |
ソースを複数端末へそろえたい場合は、正本を1か所に決め、コンパイル確認後に必要なファイルだけ各端末へ配置するほうが、削除や版違いを追跡しやすくなります。
MT5標準の共通ファイル領域¶
MQL5のファイル操作は、通常は各端末のMQL5\Filesに制限されます。FileOpenへFILE_COMMONを追加すると、同じWindowsユーザーで動くMT5が共通で使うTerminal\Common\Files側へ保存されます。
共通領域の場所はTerminalInfoString(TERMINAL_COMMONDATA_PATH)で取得できます。ただし、今回の表示パネルには実パスを出さず、FILE_COMMONを利用中であることだけを表示します。
書き込み部分の要点は次の形です。
int handle = FileOpen(
heartbeat_file,
FILE_WRITE | FILE_CSV | FILE_ANSI |
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_COMMON,
','
);
if(handle == INVALID_HANDLE)
{
PrintFormat("FileOpen failed, error=%d", GetLastError());
return false;
}
FileWrite(handle, "MQL29", channel, node, _Symbol,
EnumToString(_Period), (long)TimeLocal());
FileFlush(handle);
FileClose(handle);
FILE_COMMONは保存場所、FILE_SHARE_READとFILE_SHARE_WRITEは複数プログラムからの共有アクセス許可です。保存場所を共通にするだけでは、同時アクセス時の扱いまでは決まらないため、役割を分けて指定します。
heartbeatで「現在動いている端末」を数える¶
公開版インジケーターは、端末ごとに次の6項目を1行のCSVへ書きます。
| 項目 | 役割 |
|---|---|
| マーカー | このツールのファイルかを識別 |
| チャンネル | 同じ用途の端末だけを集計 |
| ノード名 | MT5-Aのような表示名 |
| 通貨ペア | heartbeat作成時のチャート |
| 時間足 | heartbeat作成時の時間足 |
| 更新時刻 | 古いノードを除外する基準 |
初期値では2秒ごとに自分のファイルを書き直し、30秒より古いheartbeatを無効と判定します。端末が異常終了してファイルだけ残っても、永遠に「稼働中」にはなりません。
ファイル名を入力値のまま使わない¶
ノード名とチャンネルは、英数字・ハイフン・アンダースコアだけへ整形してからファイル名へ使います。区切り記号やパス文字を混ぜて、意図しない場所を指すことを防ぐためです。
読み書きを短時間で閉じる¶
heartbeatは書いたらすぐFileClose()します。読み手も1ファイルずつ開いて必要項目を検査し、すぐ閉じます。長時間ハンドルを保持しないため、別端末が更新できる時間を確保できます。
チャンネルで用途を分離する¶
同じ共通フォルダでも、チャンネルが異なるheartbeatは数えません。デモ、検証、別ツールなどを混ぜずに扱えます。
専用MT5での動作確認¶
売買無効の専用テストMT5で、本体インジケーターと検証EAをコンパイルしました。検証EAを独立した2番目のノード役にし、本体が同じ共通領域から2件を検出できることを確認しています。
| 項目 | 設定・結果 |
|---|---|
| 通貨ペア・時間足 | EURUSD・1時間足 |
| 本体ノード | MT5-A |
| 検証ノード | MT5-B |
| 検出した有効ノード | 2 |
| 最新heartbeat経過 | 0秒 |
| 共有ファイル再読込 | 成功 |
| 共通データパス取得 | 成功 |
| 本体コンパイル | 0 errors / 0 warnings |
| 検証用コンパイル | 0 errors / 0 warnings |
| キャプチャ | 成功、エラー0 |
この検証は、1台の専用MT5内で2つの書き手を再現したものです。別々のMT5プロセスを同時起動した試験ではありません。ただし、保存先が全クライアント端末共通になること自体はMQL5公式仕様であり、今回のテストではその領域への書き込み、列挙、再読込、期限判定を確認しました。
パラメータ¶
| パラメータ | 初期値 | 説明 |
|---|---|---|
InpNodeName | MT5-A | この端末を識別する表示名 |
InpChannel | mql29-demo | 同じ値の端末だけを集計 |
InpHeartbeatSec | 2 | heartbeatの更新間隔(秒) |
InpStaleSec | 30 | 稼働中とみなす最大経過秒数 |
InpShowPanel | true | チャート左上に状態を表示 |
複数端末で使う場合はInpChannelをそろえ、InpNodeNameだけを端末ごとに変えます。停止判定を安定させるため、InpStaleSecはInpHeartbeatSecより十分大きくしてください。
ダウンロード¶
29_Common_Folder_Heartbeat_v1_00.mq5 をダウンロード
MT5のIndicatorsへ保存してコンパイルし、チャートへ適用してください。注文機能はなく、共通領域へのheartbeat保存と状態表示だけを行います。
ロジック評価の結論¶
原典の課題は、複数端末へ同じファイルを手作業で配ると更新漏れが起きることでした。現在のMT5で実行時データを共有する場合は、まずFILE_COMMONを使うことで、ジャンクションより狭い範囲へ目的を限定できます。
ただし、共通フォルダは同じPC内のプログラムから見える共有領域です。秘密情報を平文で置く用途には向きません。また、同じファイルへ複数端末が同時に上書きすると競合するため、今回のようにノードごとに別ファイルを持たせる設計が扱いやすいです。
ジャンクションそのものが悪いわけではありません。必要な場合は対象を小さく絞り、MT5を停止し、実体側をバックアップしたうえで使います。共有の目的が状態データの受け渡しなら、MQL5標準機能から検討するのが安全です。
前後の記事¶
前: 【移植#28】シフトの違うMAの間へ雲を描く — 表示時刻をそろえてから塗りつぶす
次: 【移植#30】経済指標後60分の値動きを測る — 初動・最大変動・戻りを同じ基準で記録