2019年6月8日土曜日

MetaTrader を複数起動してストラテジーテスターを行う方法

MetaTrader は `/portable` オプションを付けることで、フォルダ単位に起動することができます。
つまり、フォルダをコピーすれば複数の MetaTrader を同時起動することができるということです。

しかし、都度フォルダをコピーするのは大変そして、history が大きくなると時間がかかる。
そこで、MetaTrader を簡単に複数起動することができるスクリプトを作ってみました。

Windows のジャンクション機能を使っているので、普通にコピーするより速く起動します。




### terminal_for_tester.js を作成
`metatrader.exe` と同じフォルダに 以下のスクリプトを置きます。

```javascript `title: "terminal_for_tester.js"; var shell = WScript.CreateObject('WScript.Shell'); var fso = WScript.CreateObject('Scripting.FileSystemObject'); // Create temporary folder var tmpFolder = fso.GetSpecialFolder(2) + '\\' + fso.GetTempName(); fso.CreateFolder(tmpFolder); // Make junctions of subfolders except 'tester' { var enuFolders = new Enumerator(fso.GetFolder('.').SubFolders) for (; !enuFolders.atEnd(); enuFolders.moveNext()) { var folder = enuFolders.item(); if (folder.Name == 'tester') continue; shell.Run('cmd.exe /c mklink /j ' + tmpFolder + '\\' + folder.Name + ' ' + folder, 0); } } // Create 'tester\files' folder fso.CreateFolder(tmpFolder + '\\tester'); fso.CreateFolder(tmpFolder + '\\tester\\files'); // Copy exe file var SRC_FILE = 'terminal.exe'; var DST_FILE = tmpFolder + '\\' + SRC_FILE; fso.CopyFile(SRC_FILE, DST_FILE); shell.Run('cmd.exe /c start /wait "' + tmpFolder + '" "' + DST_FILE + '" /portable', 0, true); // Delete temporary dir { fso.DeleteFolder(tmpFolder + '\\tester', false); // Unlink the junctions var enuFolders = new Enumerator(fso.GetFolder(tmpFolder).SubFolders) for (; !enuFolders.atEnd(); enuFolders.moveNext()) { var folder = enuFolders.item(); shell.Run('cmd.exe /c rmdir ' + folder, 0, true); } // Make sure that the unlinking has been completed do { WScript.Sleep(100); var subFolders = fso.GetFolder(tmpFolder).SubFolders } while (subFolders.Count != 0); fso.DeleteFolder(tmpFolder, false); } ``` WSH (JScript) なので複雑に見えますがなぜ WSH にしたかというと、ダブルクリックでスマートに起動したかったからだけ、やっていることは単純です。 一時フォルダを作成し、その中に `tester` フォルダ以外のジャンクションをはります。その後、`terminal.exe` をコピーして実行するだけです。 起動後の一時フォルダ削除が少々複雑ですが、ジャンクション削除のお作法です。 なお、`terminal.exe` は勝手にアップデート問題があるため、コピーにしています/skipupdate というオプションもありますが、最近のものでは動作していない気がする。 > 参考 > > [MetaTrader 4 は勝手に再起動してアップデートすることがある | Strategy of C](https://strategyofc.blogspot.com/2018/12/metatrader-4.html) ### 起動 `terminal_for_tester.js` をダブルクリックで起動。何個でも起動します。 あえてアイコンはコピーしていません。 デフォルトのアイコンになるので、区別しやすいかと思います。
### 注意点 使用上の注意点がいくつかあります。 #### history フォルダはバックアップしておいた方がよい history フォルダを共有しているので、複数のプロセスから書き込みが行われると不整合が起こる可能性があります。 基本的には `terminal.exe` の終了時に上書きが走るようなので、同時に閉じないようにすれば大丈夫な気がしていますが、確かではありません。 私はオフラインにして履歴が更新されないようにしていますが、そこまではしなくても良いかもしれません。 #### `tester\files` フォルダは消えてしまう 実行しているフォルダは MetaTrader の実行が終わると削除されてしまいます。同時に `tester\files` フォルダも消えてしまいます。 結果をファイルに出力する等している場合、別フォルダに移動する必要がありますそれをスクリプトに書いてもいいかもしれない。 #### 同時に実行する数に注意 CPU のコア数までは複数起動してもあまりパフォーマンスには影響しないでしょうストレージへのアクセス時は若干遅くなるはず。 論理プロセッサ数を超えるとパフォーマンスは下がっていくと思いますが、倍くらいまでならそれなりに動くのではないかと思います。 参考にして下さい。 余談ですが、CPU の情報は「タスクマネージャー」で見ることができます。 タスクバー右クリック → タスクマネージャー
パフォーマンスタブの CPU