问题描述
2026-01-27 10:51:07 253323 报警信息 紧急 账号 [253323] 撤单失败 [-1], CTP:无效的 ExchangeID 字段,请填入正确的 ExchangeID
2026-01-27 10:51:01 253323 报警信息 紧急 账号 [253323] 撤单失败 [-1], CTP:无效的 ExchangeID 字段,请填入正确的 ExchangeID
但是实际上,存在两个同步撤单 api;http://dict.thinktrader.net/nativeApi/xttrader.html#%E8%82%A1%E7%A5%A8%E5%90%8C%E6%AD%A5%E6%92%A4%E5%8D%95
我用两个参数的,就会报错。
image.png
实际上我都没有传入“market - int 交易市场”的参数
解决方案
报错原因分析
在 miniqmt(xtquant)或 QMT 平台中进行撤单操作时,如果遇到 CTP:无效的ExchangeID字段,请填入正确的 ExchangeID 的紧急报警,通常是因为底层交易网关(特别是期货 CTP 柜台或部分股票柜台)在接收撤单指令时,未能获取到该笔委托对应的交易市场(ExchangeID,如 SH、SZ、IF 等)。
您提到使用了“两个参数的同步撤单 API”且没有传入 market 参数。在部分简化的撤单 API 中(例如仅传入 account 和 order_id),如果系统在本地缓存中无法通过 order_id 反查到对应的 market,就会向柜台发送一个空的 ExchangeID,从而导致 CTP 柜台直接拒单并返回上述错误。
解决办法
为了确保撤单指令能够被柜台正确识别,强烈建议在撤单时显式传入市场(market/ExchangeID)参数,或者使用完整的委托对象进行撤单。
方法一:使用带 market 参数的撤单 API(针对 miniqmt/xtquant)
在 xttrader 中,如果您使用的是根据系统委托号撤单的接口,请改用包含 market 参数的版本。例如:
# 假设您使用的是 xtquant.xttrader
# 不要使用仅传 account 和 order_id 的简化版本
# 请使用明确指定 market 的接口,例如:
xt_trader.cancel_order_stock_sysid(account, market, order_sysid)
参数说明:
account: 资金账号对象market: 交易市场(如 'SH', 'SZ', 'IF' 等,需与原委托一致)order_sysid: 柜台系统委托号
方法二:通过获取委托对象进行撤单(推荐)
最稳妥的撤单方式是先查询到该笔委托的完整对象(Order 对象),然后直接对该对象发起撤单。这样底层会自动提取 ExchangeID。
# 1. 获取当前未成交的委托列表
orders = xt_trader.query_stock_orders(account)
for order in orders:
# 2. 找到需要撤销的委托(例如根据自定义的 order_remark 或 order_id)
if order.order_sysid == '您的委托号':
# 3. 传入完整的 order 对象进行撤单,底层会自动解析 order.market / order.exchange_id
xt_trader.cancel_order_stock(account, order)
print(f"已发送撤单指令,委托号: {order.order_sysid}, 市场: {order.market}")
补充:QMT 内置 Python API 的撤单方式
如果您是在 QMT 平台内部(非独立 miniqmt)编写策略,根据 QMT API 文档,标准的撤单函数为 cancel,其用法如下:
def handlebar(ContextInfo):
# 获取最新的委托号
orderid = get_last_order_id(ContextInfo.accid, 'stock', 'order')
if orderid != '-1':
# 检查是否可撤销
if can_cancel_order(orderid, ContextInfo.accid, 'stock'):
# 执行撤单
cancel(orderid, ContextInfo.accid, 'stock', ContextInfo)
print(f"执行撤单: {orderid}")
总结
CTP:无效的ExchangeID字段 的根本原因是撤单报文中缺失了市场代码。放弃使用省略 market 参数的重载函数,改用显式传递 market 的 API,或直接传递完整的 Order 对象,即可完美解决此问题。