下单、撤单与结果跟踪

即时提交结果、订单终态、拆单及未知结果处理。

本页目录

下单会向真实期货公司提交委托。先在适当测试环境充分验证策略。本文片段假定已经创建 CTP 账户、观察订单并完成同步;完整下载示例要求显式传入 --execute 才会下单。

限价委托

if api.trading_status() != "READY":
    raise RuntimeError("交易账户尚未就绪")

results = api.insert_order(
    symbol=symbol,
    direction="BUY",
    offset="OPEN",
    volume=1,
    limit_price=limit_price,
)
tracked_ids = set()
for result in results:
    print(result.status, result.order_id, result.message)
    if result.status in {"SUBMITTED", "UNKNOWN"} and result.order_id:
        tracked_ids.add(result.order_id)

direction 为 BUY / SELL;输入 offset 为 OPEN / CLOSE。volume 为正整数手数,limit_price 为符合最小变动价位的有效限价。SDK 仅支持普通投机限价委托。

即时提交结果

TradingResult.status含义正确处理
SUBMITTED已交给交易接口等待订单回报;不等于柜台接受或成交
REJECTED本地拒绝或明确未发送检查 message;下单不会创建订单,order_id 为 None
UNKNOWN提交结果不明保留订单号等待自然回报,不自动重发

返回值为 list[TradingResult],并非订单号列表。拆单会产生多个子单结果;前一子单失败或结果不明时,剩余子单可能返回未发送的拒绝结果。CLOSE 由 SDK 按合约和可平持仓规则处理,实际订单快照中的 offset 还可能是 CLOSE_TODAY / CLOSE_YESTERDAY。

跟踪最终状态

在下单前创建 orders = api.watch_order(),之后通过同一个更新循环跟踪:

while tracked_ids:
    api.wait_update()
    if api.trading_status() != "READY":
        continue
    snapshot = orders.data()
    for order_id in list(tracked_ids):
        order = snapshot.get(order_id)
        if order is None:
            continue
        print(order_id, order.status, order.volume_traded, order.status_msg)
        if order.status in {"FILLED", "CANCELLED", "REJECTED"}:
            tracked_ids.remove(order_id)

示例是观察逻辑,业务程序应另行提供等待期限和后续处理。PENDING 待回报;ALIVE 尚未确认终态;FILLED 全部成交;CANCELLED 未全成且不再排队;REJECTED 提交失败或被拒。取消后的 volume_left 仍可大于零。

撤单

results = api.cancel_order(order_id)
for result in results:
    print(result.status, result.order_id, result.message)

传本地 order_id,不是 order_sys_id。不存在、已结束或已经在撤单处理中的订单返回 []。尚未确认或缺少系统订单号时立即拒绝,不缓存撤单意图。最终结果查看订单的 status、cancel_pending、cancel_error,不能把撤单 SUBMITTED 当作已撤成功。

错误与退出

下单或撤单的业务拒绝一般不抛异常、不自动重试、不单独改变会话状态。线程错误、关闭后调用等仍可立即报错。关闭 ExApi 不会撤销订单;如果策略退出时需要撤单,应自行发起并跟踪结果,不盲目重发委托。

接口说明依据 exsdk 1.1.2 的公开接口与本地使用指南整理。