下单会向真实期货公司提交委托。先在适当测试环境充分验证策略。本文片段假定已经创建 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 不会撤销订单;如果策略退出时需要撤单,应自行发起并跟踪结果,不盲目重发委托。