import MetaTrader5 as mt5 # 登录账号 ACCOUNT = 12345678 PASSWORD = "your_password" SERVER = "Exness-MT5Trial" # 服务器名称 SYMBOL = "EURUSD" # 初始化 if not mt5.initialize(): print("initialize() failed:", mt5.last_error()) quit() if not mt5.login(ACCOUNT, PASSWORD, SERVER): print("login() failed:", mt5.last_error()) mt5.shutdown() quit() # 获取当前持仓 positions = mt5.positions_get(symbol=SYMBOL) if positions is None or len(positions) == 0: print(f"没有 {SYMBOL} 的持仓") mt5.shutdown() quit() # 遍历并平仓 for pos in positions: ticket = pos.ticket lot = pos.volume position_type = pos.type # 0=BUY, 1=SELL if position_type == mt5.POSITION_TYPE_BUY: # 平多 -> 发送SELL订单 close_request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": SYMBOL, "volume": lot, "type": mt5.ORDER_TYPE_SELL, "position": ticket, "price": mt5.symbol_info_tick(SYMBOL).bid, "deviation": 10, "magic": 234000, "comment": "Python Close Buy", "type_filling": mt5.ORDER_FILLING_IOC, } else: # 平空 -> 发送BUY订单 close_request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": SYMBOL, "volume": lot, "type": mt5.ORDER_TYPE_BUY, "position": ticket, "price": mt5.symbol_info_tick(SYMBOL).ask, "deviation": 10, "magic": 234000, "comment": "Python Close Sell", "type_filling": mt5.ORDER_FILLING_IOC, } result = mt5.order_send(close_request) print(result) if result.retcode != mt5.TRADE_RETCODE_DONE: print(f"平仓失败: {result.comment}, 错误码: {result.retcode}") mt5.shutdown() ''' 2️⃣ 常见平仓失败原因 未传 position 参数 在 MT5 里,如果是平仓,你必须指定 原单的 ticket ID(即 position 字段)。 不然系统会认为你是开新仓,而不是平仓。 价格方向不对 平多必须用 SELL,平空必须用 BUY,价格要对应 bid 或 ask。 多单平仓价用 Bid(卖给市场),空单平仓价用 Ask(买回)。 lot 不匹配 发送的 volume 必须和剩余仓位量一致(或等于合约最小手数的整数倍)。 有些券商要求精确到 2~3 位小数,否则 Invalid volume。 订单类型与服务器支持不符 type_filling 要用服务器支持的方式(常见 ORDER_FILLING_IOC)。 有些外汇服务器不支持 FOK。 symbol 没有准备好 必须 mt5.symbol_select(SYMBOL, True),并且 symbol_info_tick() 不为 None。 '''