FX
MT5とPythonを接続してFX自動売買の価格取得を確認する手順

MT5とPythonを連携するときは、まずWindows上の対象MT5端末へ接続し、銘柄の価格を取得するところまでを確認します。MetaTrader5パッケージを入れただけで、どの口座へ接続しても同じように使えるわけではありません。接続先の端末、デモ口座、銘柄名をそろえて進めましょう。
この記事は、FX自動売買へ分析データを渡す前の準備として、注文を送らない価格取得を扱います。環境の確認、初期化、ティックと確定足の取得、失敗した段階の切り分けを説明します。いきなり発注処理を加えるより、どのデータを取得できたかを一つずつ照合する方が原因を追いやすくなります。
- 公式パッケージと対応するOS・Pythonの確認方法
- 複数のMT5から接続先を取り違えない準備
- 発注せず最新ティックと確定足を取得するコード
- 接続失敗と価格・履歴の取得失敗を分ける順序
MT5とPythonをFX自動売買の検証へ接続する

PythonとMT5端末の役割を分ける
ここで使うMetaTrader5パッケージは、PythonからローカルのMT5端末へ接続するためのものです。取引会社の汎用REST APIへ直接アクセスするコードとは構成が違います。端末側のインストールやログイン、接続状態を確認する工程が必要になります。
Python側は、価格の取得や分析などを担当します。端末側は、選択した取引サーバーや銘柄のデータを提供します。Pythonで接続関数が成功したことと、想定したサーバーから必要な価格を受け取れたことは別です。両者を一つの「接続できた」でまとめないようにします。
また、Pythonのスクリプトと、MT5のチャート上で動くMQL5のEAは別の実行方法です。PythonのファイルをEA用フォルダへ置けば自動で同じように動く、という関係ではありません。まず一回実行してデータを読み、接続を閉じる小さな処理で確かめます。
公式の機能一覧はMetaQuotesのPython連携リファレンスにあります。本記事では注文関数を呼ばず、接続とデータの対応だけを確認します。
対応する配布ファイルと実行環境を確認する

最初に確認するのは、使うパッケージ名です。公式の案内先はMetaTrader5です。似た名称の別パッケージや追加ラッパーを、同じものとしてインストールしないようにしましょう。検索結果の順位だけで選ばず、公式ドキュメントから配布元を確認します。
執筆時点のPyPIでは、MetaTrader5の配布ファイルにWindows x86-64向けのタグが付いています。使用するCPythonの版に対応するファイルがあるかも確認します。MT5本体が別OSで動く構成と、このPythonパッケージをそのOSへ直接導入できることは、別の確認事項です。
MacやLinuxで同じコマンドが通らない場合、まず配布対象を見直します。非公式の回避策を足して先へ進むより、この手順は対応するWindows環境を用意して確認する方が範囲を明確にできます。OSやPythonの新しい版へ対応したかは、実行する時点の配布ファイルで再確認してください。
対応状況の確認先はPyPIのMetaTrader5配布ページです。記事中に特定のPython版を永続的な推奨値として固定せず、現在入手できるファイルと実行環境を合わせることが大切です。
仮想環境へ入れてimportを確かめる
検証用のフォルダで仮想環境を作ると、他のプロジェクトのパッケージと分けて確認できます。以下はWindowsのPowerShellで、使用するPythonが選べている場合の例です。複数版を入れている方は、最初のpyが対応する版を選んでいるかを先に確認してください。
py -m venv .venv
.\.venv\Scripts\python.exe -m pip install MetaTrader5
.\.venv\Scripts\python.exe -c "import MetaTrader5 as mt5; print(mt5.__version__)"
インストールと実行には、同じ仮想環境のpython.exeを使います。普段のpipで導入し、別のPythonやノートブックでimportすると、入れたはずなのに見つからない状態になることがあります。導入先と実行元の対応を確認してから、パッケージ自体の問題を疑いましょう。
「対応する配布ファイルがない」という種類のエラーでは、OS、アーキテクチャ、CPythonの版、配布ファイルのタグを照合します。ModuleNotFoundErrorでは、まず実行する環境へ導入されているかを確認します。どちらも、取引口座のパスワードを変更して直す種類の問題ではありません。
importして版が表示されても、MT5端末との接続までは未確認です。次に進む前に、どの端末を起動し、どのデモ口座を使うかを決めます。必要がない段階で、追加の分析ライブラリや発注用ラッパーを一度に導入しない方が、失敗箇所を絞りやすくなります。
接続する端末とデモ口座を決める

複数業者のMT5がある場合、引数なしのinitializeは意図した端末を選ぶとは限りません。公式仕様では、引数なしで接続先を自動検索する形式と、端末実行ファイルを最初の位置引数で指定する形式があります。今回は接続先を明示する方法を使います。
対象のWindows端末で、MT5の実行ファイルを確認し、その場所を環境変数MT5_TERMINAL_PATHへ設定します。これは記事中の固定パスをコピーする手順ではなく、ご自身が使用する実行ファイルを指定する準備です。環境変数を設定した後は、その値を参照できる新しいPowerShellから実行します。
端末では検証用のデモ口座へログインし、サーバー名と口座の種類を画面で確認します。以下のコードは端末に保存済みの接続を使うため、ソース内へパスワードを埋めません。口座番号やパスワードを、質問サイトや共有リポジトリへ貼り付けないようにしてください。
初期化の引数と、指定しない場合の口座の扱いはinitializeの公式仕様を参照してください。端末への接続先指定と、取引口座の照合は両方行います。
銘柄と気配値の更新を端末で確認する
コードへ渡す銘柄名は、対象口座の気配値表示から確認します。EURUSDのような一般名と、接尾辞付きの実銘柄名を取り違えないようにします。同じ通貨ペアでも、口座や業者によって表示名・取引条件が異なる場合があります。
まず端末の気配値表示へ対象を出し、取引時間内なら価格が更新されるかを見ます。端末側でデータを受け取れていない状態を、Pythonの分析処理で補うことはできません。週末など市場が休んでいれば、最後の価格が存在しても更新が止まっている場合があります。
次のコードは、端末の表示リストを勝手に変更せず、対象銘柄が選択されていることを確認してから読みます。symbol_selectを使ってPythonから表示対象を選ぶこともできますが、その場合は気配値表示の状態を変える操作です。価格の読取と区別して扱います。
MT5とPythonで価格取得を照合する

発注しない最小コードで接続を試す
下は、指定した端末とデモ口座を確認し、銘柄のティックと5本の確定足を読む例です。環境変数MT5_SYMBOLには、事前に選択した実銘柄名を設定します。初期値を適当な銘柄名で埋めないため、未設定なら終了します。注文送信・変更・決済の関数は呼びません。
このコードは学習用の構成例です。構文と公式の関数仕様を照合した上で掲載していますが、すべての取引会社・端末版の実環境で動作確認済みの製品として扱うものではありません。まず専用のデモ環境で確認してください。
import os
from datetime import datetime, timezone
import MetaTrader5 as mt5
terminal_path = os.environ.get("MT5_TERMINAL_PATH", "").strip()
symbol = os.environ.get("MT5_SYMBOL", "").strip()
if not terminal_path or not symbol:
raise SystemExit("Set MT5_TERMINAL_PATH and MT5_SYMBOL first.")
if not mt5.initialize(terminal_path, timeout=60000):
error = mt5.last_error()
mt5.shutdown()
raise SystemExit(f"initialize failed: {error}")
try:
terminal = mt5.terminal_info()
account = mt5.account_info()
if terminal is None or account is None:
raise RuntimeError(f"Information unavailable: {mt5.last_error()}")
expected_dir = os.path.normcase(os.path.abspath(os.path.dirname(terminal_path)))
actual_dir = os.path.normcase(os.path.abspath(terminal.path))
if actual_dir != expected_dir:
raise RuntimeError("Wrong MT5 terminal.")
if not terminal.connected:
raise RuntimeError("Server disconnected.")
if account.trade_mode != mt5.ACCOUNT_TRADE_MODE_DEMO:
raise RuntimeError("Demo account required.")
info = mt5.symbol_info(symbol)
if info is None:
raise RuntimeError(f"Unknown symbol: {mt5.last_error()}")
if not info.visible:
raise RuntimeError("Select symbol in Market Watch.")
tick = mt5.symbol_info_tick(symbol)
if tick is None:
raise RuntimeError(f"Tick read failed: {mt5.last_error()}")
print("Symbol:", symbol, "Bid:", tick.bid, "Ask:", tick.ask)
print("Tick UTC:", datetime.fromtimestamp(tick.time, timezone.utc).isoformat())
rates = mt5.copy_rates_from_pos(symbol, mt5.TIMEFRAME_M5, 1, 5)
if rates is None:
raise RuntimeError(f"Bar read failed: {mt5.last_error()}")
if len(rates) != 5:
raise RuntimeError(f"Expected 5 bars, received {len(rates)}.")
for bar in sorted(rates, key=lambda row: int(row["time"])):
opened = datetime.fromtimestamp(int(bar["time"]), timezone.utc)
print(opened.isoformat(), float(bar["open"]), float(bar["high"]),
float(bar["low"]), float(bar["close"]))
finally:
mt5.shutdown()

接続先の端末ディレクトリ、サーバー接続、デモ口座、銘柄の存在と表示状態を順に検査します。口座情報全体をprintせず、必要な判定だけに使う構成です。デモ口座であることはコードでも確認しますが、想定したデモ口座なのかは端末画面で別に照合してください。
途中で失敗すれば、その段階の例外を出して終了し、finallyで接続を閉じます。shutdownはPythonと端末の接続終了であり、建玉を決済する処理ではありません。他のEAや端末の動作を止める操作と混同しないようにします。
情報取得の返り値はterminal_infoとaccount_info、終了処理はshutdownの公式説明で確認できます。
ティックの存在と新しさを分ける
symbol_info_tickは、指定銘柄の最後のティックを返します。BidとAskの値だけでなく、取得したティックの時刻も確認します。戻り値がNoneではないことは、現在も価格が更新されているという保証ではありません。市場休止中には、最後に配信された値が残っていることがあります。
コードの出力と端末を比較するときは、銘柄をそろえ、時刻の差も考慮します。実行から画面確認までに新しいティックが来れば、値は一致しないことがあります。ティックが違うのか、比較する銘柄が違うのかを分けるために、価格だけでなく時刻も合わせます。
受信できたBidやAskを、そこで必ず約定できる価格と扱わないことも大切です。本記事はデータ取得の確認で、注文の受付や約定を検証するコードではありません。提示価格と取引結果の違いは、発注処理を作る段階で別に扱います。
最後のティックの定義とNoneの扱いはsymbol_info_tickの公式仕様を参照してください。
確定足とUTCをそろえて比較する
copy_rates_from_posのstart_posは、現在から過去へ数える足の位置です。0は現在形成中の足なので、例では1から5本を指定しています。これは5分足の確定した足を確認するための範囲であり、最新の未確定足を含む5本とは違います。
返されたデータはtime・open・high・low・closeなどを持つ配列です。Pythonの配列全体をif ratesで判定するのではなく、Noneかどうかと件数を分けて確認します。返却件数が不足している場合に、足りない行を0で埋めて分析を続けることは避けましょう。
時刻の変換では、タイムゾーンを明示します。公式ドキュメントはPython連携の足・ティック時刻をUTCとして扱うと説明しているため、例もtimezone.utcを指定しています。PCのローカル設定に任せた日時へ変換し、そのまま端末の表示時刻と比較しないようにします。
画面と違う時刻が出た場合は、固定の時間数を足して合ったことにする前に、APIの基準、端末表示の基準、夏時間、同じ足の四本値を照合します。取得元のデータと表示変換を分けておくと、別期間でのずれを見つけやすくなります。
足の位置と返却形式はcopy_rates_from_pos、時刻の注意点はcopy_rates_fromの公式説明で確認できます。
失敗した段階とエラーを対応させる

失敗時は、直前の関数とlast_errorの結果を一組で見ます。インストール、import、端末接続、サーバー接続、銘柄取得、ティック取得、履歴取得では、点検する対象が違います。すべてを「接続エラー」と呼ぶと、関係のない設定を変えやすくなります。
| 止まった場所 | 最初の点検対象 |
|---|---|
| pip・import | 対応する配布ファイルと同じ実行環境 |
| initialize | 対象実行ファイル、端末起動、接続処理 |
| terminal.connected | 端末側のログインと取引サーバー接続 |
| symbol_info・tick | 実銘柄名、気配値表示、配信時刻 |
| copy_ratesの件数 | 時間足、履歴の範囲、要求本数 |
last_errorは、エラーコードと説明をタプルで返します。MQL5の取引サーバーのretcodeと同じ番号体系だと決め付けず、Python連携ライブラリの一覧と照合してください。たとえば認証失敗と、端末との内部通信の失敗では、先に確認する層が異なります。
履歴が不足する場合は、対象チャートで取得できる履歴と、端末の「チャートの最大バー数」などを確認します。大量取得へいきなり広げず、まず5本で比較できる状態を作ります。失敗時に無期限で再接続を繰り返すより、一度止めて条件をそろえてから再確認する方が原因を追いやすいですね。
公式の番号一覧はlast_errorのリファレンスにあります。問い合わせで画面や出力を共有する場合は、口座番号、氏名、保存先など不要な情報を伏せてください。
MT5とPythonの接続後に進む条件
次の分析へ進む前に、意図した端末とデモ口座であること、銘柄が一致すること、ティックの時刻を説明できること、5本の足の時刻と四本値を画面で確認できることを点検します。Pythonが終了コード0で終わることだけでは、データの対応まで確認できたとは言えません。
データの読取と、利益が出るロジックの検証は別の工程です。また、Pythonスクリプトが通常実行できることと、MT5のストラテジーテスターで同じファイルをそのままEAとして検証できることも区別します。検証環境や売買判断の設計へ進む場合は、PythonでFX自動売買を作る際の設計上の確認点を参照してください。
本番の注文を追加する段階では、数量、注文方式、受付結果、約定、再接続後の残存注文など、新しい確認が必要になります。価格取得ができたからといって、そのまま本番資金へつなげないことが大切です。MT5での検証全体を考える場合は、MT5のEAバックテストの設定と結果確認も確認材料になります。
MT5とPythonの接続は、対応環境をそろえ、端末を選び、価格の時刻と中身を照合する順序で進めましょう。FX自動売買へ広げる前に、接続できた事実と、正しいデータを読めた事実を分けて説明できる状態にすることが、実装の土台になります。
EA作成ツールの検証範囲を確認する
生成コードの動作テスト・コンパイル結果と、その限界 →記事内の戦略や個別のEAの収益性を検証した結果ではありません。学んだルールを、形にしてみよう。
EA作成ツールを開く ↗