PythonからMetaTrader5を起動してEAの最適化を行い、結果をPythonに取り込む

はじめに

MetaTrader5(MT5)は、売買システム(EA)のバックテストや最適化に便利です。MT5を単独で使う場合、最適化して終わりなのですが、今回、色々な最適化ができるように、PythonからMT5の最適化を実行して、その結果をPythonに取り込んでみます。

(注)本記事の方法はMT4では使えません。設定ファイルやレポートファイルの互換性がないのです。

PythonからMT5を起動する

PythonからWindowsのアプリケーションを実行するには、subprocessモジュールを使います。MT5のプログラムがC:\Program Files\Alpari MT5\terminal64.exeだとすると、以下のコードでMT5が実行できます。

import subprocess
subprocess.run(r'C:\Program Files\Alpari MT5\terminal64.exe')

MT5を起動してEAの最適化を行う

このままだとMT5を起動するだけで、最適化は手動で操作しなくてはなりません。ところが、MT5にはコマンドラインオプションで起動時の動作を設定する機能があります。設定ファイル(ここでは、C:\MT5\myconfig.iniとします。内容は後述します。)を用意しておき、次のように/config:オプションで設定ファイルを指定することができます。

import subprocess
subprocess.run(r'C:\Program Files\Alpari MT5\terminal64.exe /config:C:\MT5\myconfig.ini')

これを実行すると、MT5を起動した後に設定ファイルで指定した内容を自動的に実行します。

最適化のための設定ファイル

EAの最適化を行うための設定ファイルの記述例です。

myconfig.ini
[Tester]
;--- テストするEAの名前(MQL5\Expertsの下)
Expert=Examples\MACD\MACD Sample

;--- テストするEAのパラメータファイル(MQL5\Profiles\Testerの下)
ExpertParameters=MACD Sample.set

;--- テストする通貨ペア
Symbol=EURUSD_i

;--- テストするタイムフレーム
Period=H1

;--- テスト用の口座番号
;Login=123456

;--- 初期資産
Deposit=100000

;--- テスト用のレバレッジ
Leverage=1:100

;--- ティック生成モデル(0:全ティック、1:1分足OHLC、2:始値のみ、3:数値計算、4:リアルティックに基づいたすべてのティック)
Model=1

;--- 約定モード(0:遅延なし、-1:ランダム遅延 >0:ミリ秒単位のカスタム遅延)
ExecutionMode=0

;--- 最適化の種類(0:無効、1:完全アルゴリズム、2:遺伝的アルゴリズム、3:気配値表示で選択されたすべての銘柄)
Optimization=1

;--- 最適化基準(0:バランスの最大値、1:バランスと利益の積の最大値、2:バランスと期待利益の積の最大値、3:バランスと(100% - ドローダウン%)の積の最大値、4:バランスとリカバリファクタの積の最大値、5:バランスとシャープレシオの積の最大値、6:OnTester()で定義されたカスタム基準)
OptimizationCriterion=0

;--- テストする期間
FromDate=2017.01.01
ToDate=2018.01.01

;--- フォワードテストモード(0:無効、1:テスト期間の1/2、2:テスト期間の1/3、3:テスト期間の1/4、4:カスタム)
ForwardMode=0

;--- フォワードテスト開始日(ForwardMode=4の場合のみ)
;ForwardDate=2011.03.01

;--- レポートファイル名(データフォルダの下、テスト:Report.htm、最適化:Report.xml)
Report=MACD Sample

;--- レポートファイルの上書き(0:無効、1:有効)
ReplaceReport=1

;--- テスト終了時のターミナルのシャットダウン(0:無効、1:有効)
ShutdownTerminal=1

MT5をご利用になったことのある方でしたら、コメントの説明だけでわかるかと思います。簡単に言うと、「MACD Sample」というEAをEURUSDの2017年の1時間足のチャートを使ってバックテストを行うということです。

ただし、EAのパラメータは、下図のように設定されているものとします。

image.png

変化させるパラメータはMA trend periodのみで、それを10から30まで1刻みで変えるようになっています。要は、MA trend periodの値を21通り変化させてバックテストを行って、それぞれの評価値を出力するわけです。

MACD Sample.setのパラメータファイルは、自動的に作成されます。EAと別の名前にしたければ、上の画面で右クリックして保存するか、別途ファイルを作成してください。

最適化の結果の出力

最適化した結果は、下図のように21回のパスに対する損益、プロフィットファクター、リカバリーファクター、最大ドローダウンなどの値が表形式で出力されます。

image.png

このデータは設定ファイルで指定したファイル名(ここでは、MACD Sample.xml)にも出力されます。

最適化の結果をPythonに取り込む

MACD Sample.xmlはMT5のデータフォルダの下に出力されるので、そのままPythonに取り込むには、そのパスを書く必要があります。パス名は長いので、ここでは、C:\MT5\MACD Sample.xmlにコピーしたものを使います。

xmlファイルからデータを取り出す方法は色々とあるようなのですが、今回はBeautifulSoup使ってみます。

まずは、次のようなコードでxmlファイルをオープンしてBeautifulSoupのオブジェクトを作成します。

from bs4 import BeautifulSoup
with open(r'C:\MT5\MACD Sample.xml') as fp:
    soup = BeautifulSoup(fp, 'xml')

このxmlファイルは、各行のデータが<Row>タグで囲まれており、それぞれの要素が<Data>タグで囲まれているので、次のようなコードでpandasのDatFrameオブジェクトに取り込んでみます。

import pandas as pd
df = pd.DataFrame()
for r,row in enumerate(soup.find_all('Row')):
    for c,cell in enumerate(row.find_all('Data')):
        df.loc[r, c] = cell.string

dfを表示させると

0 1 2 3 4 5 6 7 8 9 10
0 Pass Result Profit Expected Payoff Profit Factor Recovery Factor Sharpe Ratio Custom Equity DD % Trades InpMATrendPeriod
1 5 100355.2900 355.2900 3.6254 1.2061 0.8486 0.0704 0 0.4167 98 15
2 3 100280.7100 280.7100 2.6734 1.1523 0.6660 0.0532 0 0.4195 105 13
3 1 100251.2700 251.2700 2.1850 1.1252 0.6364 0.0440 0 0.3930 115 11
4 6 100249.4400 249.4400 2.6822 1.1509 0.5178 0.0524 0 0.4794 93 16
5 2 100243.0300 243.0300 2.2094 1.1258 0.5938 0.0442 0 0.4075 110 12
6 4 100227.0700 227.0700 2.2262 1.1224 0.5283 0.0437 0 0.4278 102 14
7 7 100217.4700 217.4700 2.3898 1.1337 0.4474 0.0467 0 0.4838 91 17
8 14 100177.5200 177.5200 2.3669 1.1532 0.4044 0.0481 0 0.4377 75 24
9 8 100177.1400 177.1400 2.0130 1.1166 0.3634 0.0399 0 0.4851 88 18
10 17 100115.3300 115.3300 1.6960 1.1112 0.3117 0.0342 0 0.3689 68 27
11 9 100114.6000 114.6000 1.3172 1.0748 0.2312 0.0260 0 0.4935 87 19
12 10 100103.2100 103.2100 1.2287 1.0694 0.2024 0.0241 0 0.5078 84 20
13 18 100102.6900 102.6900 1.5559 1.0985 0.2566 0.0309 0 0.3990 66 28
14 13 100088.8100 88.8100 1.1841 1.0768 0.1900 0.0245 0 0.4660 75 23
15 0 100059.7200 59.7200 0.4855 1.0259 0.1034 0.0097 0 0.5751 123 10
16 12 100057.9400 57.9400 0.7525 1.0471 0.1089 0.0156 0 0.5303 77 22
17 19 100050.7000 50.7000 0.7800 1.0486 0.1267 0.0156 0 0.3990 65 29
18 16 100033.3000 33.3000 0.4757 1.0292 0.0704 0.0097 0 0.4717 70 26
19 11 100026.9300 26.9300 0.3325 1.0186 0.0526 0.0067 0 0.5102 81 21
20 15 100025.2700 25.2700 0.3510 1.0218 0.0517 0.0073 0 0.4872 72 25
21 20 100016.1100 16.1100 0.2517 1.0153 0.0372 0.0052 0 0.4323 64 30

となり、各データが読み込まれていることがわかります。

この結果を使って、さらに条件を変えて繰り返しMT5で最適化させることで、MT5だけではできないようなEAの最適化ができるのではないかと思います。具体的な方法についてはまた次回。

参考記事

Pythonのコード書くの久しぶりだったので、色々な記事を参考にさせていただきました。特にpandas.read_excel()でうまくいかなかったときには、以下の記事を参考にさせていただきました。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.