MT5 Python 整合:用 MetaTrader5 套件進行量化交易

📌 本文重點
完整學習 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 撰寫。內容僅供教育目的,不構成投資建議。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *