見出し画像

Python-EAの作り方(PythonスクリプトをMT5のチャート上で直接実行する方法)

MT5(MetaTrader5)では、Pythonスクリプトを通常のMQL5プログラムと同様にチャート上で直接実行できる機能が存在します。

以下の画像の右上に、「Python-EA」という表示があるのをご確認いただけるでしょうか。

Pythonスクリプトの実行

これが、PythonスクリプトをMT5のチャートに設置して実行中の画面です。

この記事では、実際に取引可能なロジックを用いて、Python-EAを作成する方法をご紹介します。MQL5で作成したEAと同様にチャート上にドラッグ&ドロップするだけで起動可能ですので、是非体験してみてください。


事前準備

いくつか事前準備が必要です。主に以下の3つですが、既に環境が整っている方は省略可能です。

  • MT5のインストール

  • Pythonのインストール

  • コンパイラの設定

MT5のインストール

この記事では、MT5がインストールされている前提で話を進めます。インストールされていない方は、以下の記事を参照する等してインストールを完了してから進んでください。

Pythonのインストール

Pythonもインストールしておく必要がありますが、ここでは今回の目的に応じた最低限の内容のみ記載します。

  1. こちらのリンクから、Pythonをダウンロードして起動します。今回は、Python3.9のWindows(64bit)用である「python-3.9.13-amd64.exe」をダウンロードした前提で話を進めます。

  2. "Add Python 3.x to PATH" をチェックし、Install now をクリックしてインストールが完了するのを待ちます。

  3. スタートボタンをクリックし、「Windows システム ツール」 の 「コマンド プロンプト」を起動します。

  4. コマンドプロンプト上で「pip install MetaTrader5」と入力し、Enterキーを押下します。「Successfully installed MetaTrader5-5.0.45」のような表示が出れば、MetaTrader5ライブラリのインストールが完了です。

コンパイラの設定

MetaEditorを起動します。以下のようにMetaTrader5とセットになっています。

MetaTrader5

MetaEditorの「ツール」→「オプション」から、「コンパイラ」タブに移動します。そして、Pythonという欄に以下のようにPythonがインストールされたフォルダのパスを入力します。

ツール > オプション > コンパイラ

標準的なインストールパスは以下の通りです。
C:¥Users¥[ユーザー名]¥AppData¥Local¥Programs¥Python¥Python[バージョン]¥
[ユーザー名]はご自身のPCに合わせたものに入れ替えてください。
[バージョン]は、Python3.9をインストールしていればPython39になっているはずです。

Pythonスクリプトの作成

続いて、MetaEditor上の「新規作成」タブをクリックすると以下の画面になりますので、ここでPythonスクリプトを選びます。

Pythonスクリプト

次の画面では、Pythonスクリプトのファイル名を指定します。

ファイル名の指定

名前はPython-EAにして、著作者とリンクは特に必要ないので空白にしました。すると、MQL5フォルダのScriptsフォルダに、以下のようにPython-EA.pyというファイルが作成されることになります。

MQL5 > Scripts

次に、以下の画面に切り替わります。必要なライブラリを選択するのですが、今回はMetaTrader 5ライブラリしか使いませんので、チェックを入れて完了をクリックします。

ライブラリの指定

すると、MetaEditor上で以下の内容が立ち上がります。

MetaEditor

こちらは、 PythonでMT5を扱う上で最低限の内容になっています。ご覧の通り、# you code hereという記載があり、ここの部分に必要な処理を追記することになります。

Pythonスクリプトの更新

mt5.initialize()とmt5.shutdown()の間に、以下の内容を記載します。最終的には以下のような形になります。(これがコード全文です。)


import MetaTrader5 as mt5

mt5.initialize()

# Input設定
symbol = 'GOLD' # 取引対象
first_lot = 0.01 # 初期ロット 
nanpin_range = 200 # ナンピン幅 
profit_target = 143 # 利益目標 
magic_number = 10001 # マジックナンバー 
slippage = 10 # スリッページ

point=mt5.symbol_info(symbol).point # 価格の最小単位


while 1:
    
    symbol_tick=mt5.symbol_info_tick(symbol) # symbolのtick情報を取得

    
    # ポジションの確認
    
    buy_position = 0 # buyポジション数の初期化
    sell_position = 0 # sellポジション数の初期化
    buy_profit = 0 # buy_profitの初期化
    sell_profit = 0 # sell_profitの初期化
    current_buy_lot = 0 # 最新のbuyポジションのlot数の初期化
    current_sell_lot = 0 # 最新のsellポジションのlot数の初期化

    positions=mt5.positions_get(group='*'+symbol+'*') # ポジション情報を取得
    
    for i in range(len(positions)): # 全てのポジションを確認
        order_type = positions[i][5] # buyかsellか取得
        profit = positions[i][15] # ポジションの含み損益を取得
        
        if order_type == 0: # buyポジションの場合
            buy_position += 1 # buyポジションのカウント
            buy_profit += profit # buyポジションの含み損益に加算
            current_buy_lot = positions[i][9] # 最新のbuyポジションのlot数を取得
            current_buy_price = positions[i][10] # 最新のbuyポジションの取得価格を取得
            
        if order_type == 1: # sellポジションの場合
            sell_position += 1 # sellポジションのカウント
            sell_profit += profit # sellポジションの含み損益に加算
            current_sell_lot = positions[i][9] # 最新のsellポジションのlot数を取得
            current_sell_price = positions[i][10] # 最新のsellポジションの取得価格を取得
    
    
    # 新規buyエントリー
    
    if buy_position == 0: # buyポジションがない場合

        request = {
                    'symbol': symbol, # 通貨ペア(取引対象)
                    'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                    'type': mt5.ORDER_TYPE_BUY, # 成行買い注文
                    'volume': first_lot, # ロット数
                    'price': symbol_tick.ask, # 注文価格
                    'deviation': slippage, # スリッページ
                    'comment': 'first_buy', # 注文コメント
                    'magic': magic_number, # マジックナンバー
                    'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                    'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                    }

        result = mt5.order_send(request)
    
    
    # 新規sellエントリー
    
    if sell_position == 0: # sellポジションがない場合

        request = {
                    'symbol': symbol, # 通貨ペア(取引対象)
                    'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                    'type': mt5.ORDER_TYPE_SELL, # 成行買い注文
                    'volume': first_lot, # ロット数
                    'price': symbol_tick.bid, # 注文価格
                    'deviation': slippage, # スリッページ
                    'comment': 'first_sell', # 注文コメント
                    'magic': magic_number, # マジックナンバー
                    'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                    'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                    }

        result = mt5.order_send(request)
    
    # 追加buyエントリー
    
    if buy_position > 0 and symbol_tick.ask < current_buy_price - nanpin_range * point:

        request = {
                    'symbol': symbol, # 通貨ペア(取引対象)
                    'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                    'type': mt5.ORDER_TYPE_BUY, # 成行買い注文
                    'volume': round(current_buy_lot * 1.5+0.001,2), # ロット数
                    'price': symbol_tick.ask, # 注文価格
                    'deviation': slippage, # スリッページ
                    'comment': 'nanpin_buy', # 注文コメント
                    'magic': magic_number, # マジックナンバー
                    'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                    'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                    }

        result = mt5.order_send(request)
    
    # 追加sellエントリー
    
    if sell_position > 0 and symbol_tick.bid > current_sell_price + nanpin_range * point:

        request = {
                    'symbol': symbol, # 通貨ペア(取引対象)
                    'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                    'type': mt5.ORDER_TYPE_SELL, # 成行売り注文
                    'volume': round(current_sell_lot * 1.5+0.001,2), # ロット数
                    'price': symbol_tick.bid, # 注文価格
                    'deviation': slippage, # スリッページ
                    'comment': 'nanpin_sell', # 注文コメント
                    'magic': magic_number, # マジックナンバー
                    'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                    'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                    }

        result = mt5.order_send(request)
    
    # buyクローズ
    
    if buy_position > 0 and buy_profit > profit_target * buy_position:

        for i in range(len(positions)):
            ticket=positions[i][0] # チケットナンバーを取得
            order_type = positions[i][5] # buyかsellか取得
            lot = positions[i][9] # lot数を取得

            if order_type == 0: # buyポジションをクローズ
                request = {
                            'symbol': symbol, # 通貨ペア(取引対象)
                            'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                            'type': mt5.ORDER_TYPE_SELL, # 成行売り注文
                            'volume': lot, # ロット数
                            'price': symbol_tick.bid, # 注文価格
                            'deviation': slippage, # スリッページ
                            'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                            'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                            'position':ticket # チケットナンバー
                            }
                result = mt5.order_send(request)
    
    # sellクローズ
    
    if sell_position > 0 and sell_profit > profit_target * sell_position:
    
        for i in range(len(positions)):
            ticket=positions[i][0] # チケットナンバーを取得
            order_type = positions[i][5] # buyかsellか取得
            lot = positions[i][9] # lot数を取得

            if order_type == 1: # sellポジションをクローズ
                request = {
                            'symbol': symbol, # 通貨ペア(取引対象)
                            'action': mt5.TRADE_ACTION_DEAL, # 成行注文
                            'type': mt5.ORDER_TYPE_BUY, # 成行買い注文
                            'volume': lot, # ロット数
                            'price': symbol_tick.ask, # 注文価格
                            'deviation': slippage, # スリッページ
                            'type_time': mt5.ORDER_TIME_GTC, # 注文有効期限
                            'type_filling': mt5.ORDER_FILLING_IOC, # 注文タイプ
                            'position':ticket # チケットナンバー
                            }
                result = mt5.order_send(request)

mt5.shutdown()

「ファイル」→「保存」で、Python-EA.pyファイルを上書き保存してください。「コンパイル」を行うとエラーがあるかどうか確認可能ですが、必ずしもコンパイルを実行しなくてもファイルが保存されていれば問題ないようです。

なお、内容は以下の記事で紹介しているものと同等ですので、ロジックの詳細等はこちらをご確認ください。

上記の記事の方法では、PythonでMT5に外部からアクセスする形でしたが、今回の方法はチャート上にPythonスクリプトを設置して動かすため、ログイン情報等をPythonスクリプト上に記載する必要が無くなっています。

MT5における稼働方法

次は、MT5(MetaTrader5)上の処理です。MetaTrader5を起動し、取引口座にログインします。ひとまずデモ口座で試してみることを推奨します。

アルゴリズム取引を許可

MetaTrader5の「ツール」→「オプション」の「エキスパートアドバイザ」タブにて、以下の2点を確認します。

  • 「アルゴリズム取引を許可」にチェックが入っている

  • 「外部Python APIを介したアルゴリズム取引を無効にする」にはチェックが入っていない

ツール > オプション > エキスパートアドバイザ

チャートの表示

続いて、GOLDのチャートを表示します。今回用意したロジックがGOLDにカスタマイズしたものであるためですが、GOLDでなくても問題ないです。
表示方法がよくわからない場合は、こちらの記事をご参照ください。

ナビゲータ内にスクリプトがあることを確認してください。ナビゲータが見当たらない場合は、「表示」タブから表示可能です。

以下の通り、スクリプト内にPython-EAが表示されていることを確認してください。もし表示されていない場合は、スクリプトを右クリックして、「更新」を実行してみてください。

ナビゲータ

チャート上にPython-EAを設置

上記のPython-EAをGOLDのチャート上にドラッグ&ドロップすると、Python-EAがチャート上に設置され、以下のようなアイコン(画像右上)が表示されるはずです。

チャート上の表示

あとは、「アルゴリズム取引」をクリックして、緑色の▷になっていることを確認してください。

稼働中

以下のように赤色の□にすれば停止できます。

停止中

なお、このロジックは取引時間内であれば、稼働後すぐに注文を行なってbuyポジションとsellポジションの両方を持つと思います。
そうでない場合は何かしら動作不具合が起こっている可能性も高く、稼働確認が行いやすい仕様になっています。
つまり、実際に取引を行なってしまうので、リアル口座ではなくデモ口座で試すなどして十分ご注意ください。

より発展的な使い方

今回のサンプルでは、テクニカル指標も使わず、シンプルなロジックのPython-EAを実装しました。

少し工夫すれば、以下のような応用も可能だと思います。

・Ta-Libをインストールして、テクニカル指標の計算も行う
・LightGBMをインストールして、機械学習も取り入れる

また試してみたら記事にします。具体的には、以下の記事の内容と当記事の内容を組み合わせるイメージです。

※追記
以下の記事内で、ADM-MLbot_001.py(MT5のチャート上で直接実行可能なファイル形式)をダウンロードできるように追加しました。

テクニカル指標の反映(追記)

テクニカル指標の反映のサンプルとして、以下の記事の内容のもの(ADM-BOT)をPython-EAにしました。

記事内にもある通り、必要なライブラリをインストールして、以下を実行してもエラーにならないようにしておく必要があります。

import MetaTrader5 as mt5
from datetime import datetime, timedelta
import numpy as np
import pandas as pd
import time
import pytz
import talib as ta

あとは同様で、コード全文をコピペした状態のPython-EA2.pyをScriptフォルダに保存するだけでOKです。

MQL5 > Scripts

注意点

以下にコード全文を掲載しておきますが、注意点です。

  • 記事執筆時点で稼働確認を行なっており、エラーが出ないことを確認しておりますが、その後の環境変化等で想定通りに稼働しない可能性はございます。動作保証等はいたしかねますのでご了承ください。

  • リアル口座にアクセスして取引を行うことも可能なコードになっておりますが、必ずデモ口座で事前に稼働確認をしていただくことを推奨いたします。

  • 当記事や他記事で解説しているロジック通りの動作を保証するものではございません。あくまでFX自動売買ツール開発のためのサンプルコードとしてご活用ください。

  • テキストファイルを置いて、読み込んだり更新したりする仕組みを採用しているのですが、この方法の場合、以下のフォルダ(Program Files > XMTraiding MT5)にテキストファイルを用意しないと上手くいかないようです。MT5のterminal64.exeが置いてあるフォルダです。

Program Files > XMTrading MT5

以下のファイルをダウンロードしてご使用ください。

current_ATR.txt
MC_list.txt

コード全文

ここから先は

12,327字

¥ 1,000

よろしければサポートお願いします。いただいたサポートは今後の記事の執筆に活用させていただきます。