3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
首先需要说明的是,根据聚宽官方公告,一创聚宽(实盘)已于2023-12-29停止维护,目前聚宽不提供任何形式的实盘及交易通道服务。但针对您提到的 Order 对象状态更新问题,其背后的机制在模拟盘和以往的实盘中是通用的。
您遇到的 order.filled == order.amount 不满足的问题,并不是因为底层订单没有成交,而是因为您检查的 Order 对象没有更新。
order.filled 没有更新?在 JoinQuant 中,当您调用下单函数(如 order()、order_target() 等)时,如果委托成功,系统会返回一个 Order 对象。这个返回的 Order 对象只是下单那一瞬间的“状态快照”。它是一个只读对象,其内部的属性(如 status、filled 等)不会随着实际交易的进行而自动、实时地在内存中更新。
因此,如果您在代码中一直用下单时返回的那个 order 变量去判断 order.filled == order.amount,它的值永远是下单那一刻的值(通常 filled 为 0),即使券商端已经全部成交,这个旧对象的属性也不会改变。
要获取订单的最新状态,您必须通过 API 重新向系统查询该订单的最新信息。正确的做法是使用 get_orders() 或 get_open_orders() 函数。
示例代码:
# 1. 下单并获取订单ID
my_order = order('000001.XSHE', 100, LimitOrderStyle(10.0))
if my_order is not None:
order_id = my_order.order_id
# 2. 在后续的逻辑中(比如隔几秒后,或者在 handle_data/handle_tick 中)
# 使用 get_orders 重新查询该订单的最新状态
latest_orders = get_orders(order_id=order_id)
if order_id in latest_orders:
latest_order = latest_orders[order_id]
# 3. 使用最新查询到的订单对象进行判断
if latest_order.filled == latest_order.amount:
log.info("订单已全部成交!")
elif str(latest_order.status) == 'held':
log.info("订单状态为全部成交(held)")
else:
log.info(f"订单尚未全部成交,当前成交量: {latest_order.filled}")
除了对象本身不自动更新外,实盘交易中订单状态的流转还涉及以下过程:
这个过程存在一定的网络和系统异步延迟。虽然您在券商APP上看到1秒就成交了,但量化平台接收到异步回报可能存在微小的时差。因此,在编写高频或依赖订单状态的策略时,必须通过 get_orders() 轮询或在下一个事件循环中检查最新状态,而不能假设下单后代码执行到下一行时订单就已经成交。