子供が生まれてから、ドル円のチャートをじっくり見る時間がまったくなくなりました。。。夜中に授乳で起きてはいますが、そんな時間にトレードできるはずもなく。「せめてエントリーシグナルだけでも自動で検知できれば」と思って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通知連携だけでも試してみてください。

