MT5 Python 整合:用 MetaTrader5 套件進行量化交易
📌 本文重點
完整學習 MetaTrader5 Python 套件:安裝設定、取得歷史 K 線、即時報價、下單交易、持倉管理,以及結合 pandas 與 numpy 進行量化分析。
完整學習 MetaTrader5 Python 套件:安裝設定、取得歷史 K 線、即時報價、下單交易、持倉管理,以及結合 pandas 與 numpy 進行量化分析。
安裝與連線設定
# 安裝套件(終端機執行)
# pip install MetaTrader5 pandas numpy
import MetaTrader5 as mt5
import pandas as pd
import numpy as np
from datetime import datetime
# 初始化 MT5(需先開啟 MT5 終端機)
if not mt5.initialize():
print("MT5 初始化失敗!")
quit()
# 顯示版本資訊
print(mt5.version())
# 帳戶資訊
info = mt5.account_info()
print(f"帳戶: {info.login}")
print(f"餘額: ${info.balance:.2f}")
print(f"淨值: ${info.equity:.2f}")
print(f"伺服器: {info.server}")
取得歷史 K 線數據
def get_ohlcv(symbol, timeframe, count=1000):
"""取得 OHLCV K 線數據,回傳 DataFrame"""
rates = mt5.copy_rates_from_pos(symbol, timeframe, 0, count)
if rates is None:
print(f"取得數據失敗:{mt5.last_error()}")
return pd.DataFrame()
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
df.set_index('time', inplace=True)
return df['open high low close tick_volume'.split()]
# 取得 EURUSD H1 最近 500 根 K 線
df = get_ohlcv("EURUSD", mt5.TIMEFRAME_H1, 500)
print(df.tail())
# 計算技術指標
df['ma20'] = df['close'].rolling(20).mean()
df['ma50'] = df['close'].rolling(50).mean()
def calc_rsi(series, period=14):
delta = series.diff()
gain = delta.clip(lower=0).ewm(com=period-1, min_periods=period).mean()
loss = (-delta.clip(upper=0)).ewm(com=period-1, min_periods=period).mean()
return 100 - (100 / (1 + gain/loss))
df['rsi'] = calc_rsi(df['close'])
print(df[['close','ma20','rsi']].tail())
下單與平倉
def market_buy(symbol, lots, sl_pips=50, tp_pips=100):
"""市價買入"""
info = mt5.symbol_info(symbol)
point = info.point
ask = info.ask
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": lots,
"type": mt5.ORDER_TYPE_BUY,
"price": ask,
"sl": round(ask - sl_pips * point, info.digits),
"tp": round(ask + tp_pips * point, info.digits),
"deviation": 10,
"magic": 88888,
"comment": "Python EA",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(request)
if result.retcode == mt5.TRADE_RETCODE_DONE:
print(f"買入成功!票號={result.order} 價格={result.price}")
else:
print(f"下單失敗!retcode={result.retcode} {result.comment}")
return result
def close_position(ticket):
"""平倉"""
positions = mt5.positions_get(ticket=ticket)
if not positions:
return False
pos = positions[0]
ptype = mt5.ORDER_TYPE_SELL if pos.type == 0 else mt5.ORDER_TYPE_BUY
price = mt5.symbol_info_tick(pos.symbol).bid if pos.type == 0 else mt5.symbol_info_tick(pos.symbol).ask
req = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": pos.symbol,
"volume": pos.volume,
"type": ptype,
"position": ticket,
"price": price,
"deviation":10,
"magic": 88888,
}
result = mt5.order_send(req)
return result.retcode == mt5.TRADE_RETCODE_DONE
完整 MA 交叉策略主迴圈
import time
def run_ma_cross(symbol="EURUSD", fast=10, slow=30, lots=0.01):
print(f"策略啟動:{symbol}")
while True:
df = get_ohlcv(symbol, mt5.TIMEFRAME_H1, slow+5)
if df.empty:
time.sleep(60)
continue
df['fast'] = df['close'].rolling(fast).mean()
df['slow'] = df['close'].rolling(slow).mean()
# 使用已確認的前兩根 K 線
f1,f2 = df['fast'].iloc[-2], df['fast'].iloc[-3]
s1,s2 = df['slow'].iloc[-2], df['slow'].iloc[-3]
golden = f2 <= s2 and f1 > s1
death = f2 >= s2 and f1 < s1
positions = mt5.positions_get(symbol=symbol)
has_pos = positions is not None and len(positions) > 0
if golden and not has_pos:
print(f"金叉!做多 {symbol}")
market_buy(symbol, lots)
elif death and has_pos:
print(f"死叉!平倉 {symbol}")
for pos in positions:
close_position(pos.ticket)
time.sleep(60)
try:
run_ma_cross()
except KeyboardInterrupt:
print("策略停止")
finally:
mt5.shutdown()
print("MT5 連線已關閉")
Python vs MQL5 比較
| 面向 | Python | MQL5 |
|---|---|---|
| 數據分析 | 極強(pandas, numpy, sklearn) | 中等 |
| 機器學習 | 極強 | 有限 |
| 執行速度 | 較慢(API 呼叫延遲) | 快(原生整合) |
| 策略測試器 | 需自行實作 | 內建完整回測引擎 |
| 部署方便性 | 需開啟 Python 環境 | EA 直接掛載圖表 |
| 適合場景 | 研究、ML 策略開發 | 正式部署、高頻策略 |
安裝注意事項
- 需使用 64 位元 Python 3.x,32 位元版本無法連接 MT5
- MT5 終端機必須先開啟,且同一台電腦上才能連線
- 在 Wine/Linux 環境需額外設定,建議在 Windows 上使用
本文由 James Lee 撰寫。內容僅供教育目的,不構成投資建議。