Python×MT5でドル円自動売買を始める|MAクロス検知+LINE通知の入門実装

Python実装・コード

子供が生まれてから、ドル円のチャートをじっくり見る時間がまったくなくなりました。。。夜中に授乳で起きてはいますが、そんな時間にトレードできるはずもなく。「せめてエントリーシグナルだけでも自動で検知できれば」と思ってMT5とPythonを連携させる仕組みを作り始めました。今日はその入門編をまとめます。

なぜMT5×Pythonなのか

なぜ僕がこれを調べたかというと、ドル円は24時間動く相場なので、仕事と育児をしながら手動でチャートを見るのが物理的に不可能になったからです。MT5(MetaTrader 5)は無料で使えるFXプラットフォームで、Pythonから直接操作できる公式ライブラリ「MetaTrader5」があります。これを使えば、PythonでロジックをRを書いて、MT5経由でFX会社の口座に注文を出すことができます。

完全自動売買は敷居が高いと感じる方もいると思いますが、まずは「シグナルを検知してLINE通知を送るだけ」というところから始めると楽です。今回はその第一歩として、MT5からドル円データを取得して移動平均クロスのシグナルを検知するコードを書きます。

環境構築(MT5のインストールとPythonライブラリ)

まずMT5をインストールしてください。国内FX会社(GMOクリック証券、OANDA、XMなど)がMT5に対応しています。口座開設後、MT5をダウンロードしてログインしておきます。

次にPythonライブラリをインストールします:

pip install MetaTrader5 pandas numpy

MT5はWindows専用です。MacはParallelsや仮想環境が必要なので、正直WindowsのPCがあると楽です(僕はWindows機を1台専用に用意しています)。

PythonからMT5に接続してドル円データを取得する

import MetaTrader5 as mt5
import pandas as pd
from datetime import datetime

# MT5に接続
if not mt5.initialize():
    print(f"MT5初期化失敗: {mt5.last_error()}")
    quit()

print(f"MT5バージョン: {mt5.version()}")
print(f"接続口座: {mt5.account_info().login}")

# ドル円の1時間足データを取得(直近500本)
symbol = "USDJPY"
timeframe = mt5.TIMEFRAME_H1
bars = 500

rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, bars)

if rates is None:
    print(f"データ取得失敗: {mt5.last_error()}")
    mt5.shutdown()
    quit()

# DataFrameに変換
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.set_index('time', inplace=True)

print(df.tail())
print(f"\n取得期間: {df.index[0]} 〜 {df.index[-1]}")
print(f"データ件数: {len(df)}本")

mt5.shutdown()

これを実行すると、MT5のドル円1時間足データがPandasのDataFrameとして取得できます。open/high/low/close/volumeが含まれています。

移動平均クロスのシグナル検知

次に、取得したデータから移動平均クロスのシグナルを検知するコードです。短期MA(25期間)が長期MA(75期間)を上抜けしたらロング、下抜けしたらショートのシグナルを出します。

import MetaTrader5 as mt5
import pandas as pd
import numpy as np

def get_usdjpy_signals(short_window=25, long_window=75):
    """ドル円のMAクロスシグナルを検知する"""
    if not mt5.initialize():
        print(f"MT5接続失敗: {mt5.last_error()}")
        return None

    rates = mt5.copy_rates_from_pos("USDJPY", mt5.TIMEFRAME_H1, 0, 200)
    mt5.shutdown()

    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    df.set_index('time', inplace=True)

    df['ma_short'] = df['close'].rolling(short_window).mean()
    df['ma_long']  = df['close'].rolling(long_window).mean()
    df['cross']    = np.where(df['ma_short'] > df['ma_long'], 1, -1)
    df['signal']   = df['cross'].diff()

    latest = df.dropna()
    latest_close   = latest['close'].iloc[-1]
    latest_signal  = latest['signal'].iloc[-1]
    latest_ma_short= latest['ma_short'].iloc[-1]
    latest_ma_long = latest['ma_long'].iloc[-1]

    result = {
        'time'    : latest.index[-1],
        'close'   : latest_close,
        'ma_short': latest_ma_short,
        'ma_long' : latest_ma_long,
        'signal'  : 'BUY' if latest_signal == 2 else ('SELL' if latest_signal == -2 else 'HOLD'),
        'trend'   : 'UP' if latest_ma_short > latest_ma_long else 'DOWN'
    }
    return result, df


# 実行
result, df = get_usdjpy_signals()
if result:
    print(f"現在時刻: {result['time']}")
    print(f"ドル円: {result['close']:.3f}")
    print(f"短期MA(25): {result['ma_short']:.3f}")
    print(f"長期MA(75): {result['ma_long']:.3f}")
    print(f"シグナル: {result['signal']}")
    print(f"トレンド: {result['trend']}")

シグナル検知をLINE通知に連携する

シグナルが出たときだけLINEに通知が来るようにすると、チャートを常時見なくて済みます。LINE Notify(無料)を使うと簡単です。

import requests

def send_line_notify(token, message):
    """LINEに通知を送る"""
    url = "https://notify-api.line.me/api/notify"
    headers = {"Authorization": f"Bearer {token}"}
    payload = {"message": message}
    response = requests.post(url, headers=headers, data=payload)
    return response.status_code


LINE_TOKEN = "あなたのトークン"

result, df = get_usdjpy_signals()

if result and result['signal'] in ['BUY', 'SELL']:
    message = f"""
【ドル円シグナル検知】
時刻: {result['time']}
現在値: {result['close']:.3f}円
シグナル: {result['signal']}
短期MA: {result['ma_short']:.3f}
長期MA: {result['ma_long']:.3f}
    """
    status = send_line_notify(LINE_TOKEN, message)
    print(f"LINE通知送信: ステータス{status}")
else:
    print(f"現在はシグナルなし({result['trend']} トレンド継続中)")

これをWindowsタスクスケジューラで1時間ごとに実行するように設定すれば、シグナルが出たときだけLINEに通知が届くようになります。子供の世話をしながらでも、スマホにLINEが来たときだけチャートを確認すれば済むので、時間的にかなり楽になりました。

まとめ

MT5×Pythonの連携は、最初の環境構築さえ乗り越えれば意外とスムーズに動きます。今回の移動平均クロス+LINE通知は、アルゴ入門の第一歩としておすすめです。

個人的には、まだLINE通知をトリガーに手動でエントリーするレベルですが、次のステップとしてmt5.order_send()を使った自動発注も試してみようと思っています。ただ自動発注は想定外の挙動が怖いので、まずはデモ口座でテストしてからにします笑。ぜひLINE通知連携だけでも試してみてください。

タイトルとURLをコピーしました