3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant 聚宽平台中,查询未成交订单并将其取消的操作主要涉及两个 API 函数:get_open_orders() 和 cancel_order()。
以下是具体的实现步骤和代码示例。
get_open_orders() 函数。该函数返回一个字典(dict),其中 Key 是订单 ID,Value 是订单对象(Order Object)。cancel_order() 函数进行撤销。你可以将这段逻辑放在 handle_data 中,或者更常见的是放在 after_trading_end(收盘后)或自定义的定时运行函数中,以确保清理当天的挂单。
以下是一个完整的策略代码示例,展示了如何在每天收盘后自动撤销所有未完成订单:
# -*- coding: utf-8 -*-
def initialize(context):
# 设置基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 每天收盘后执行撤单逻辑
# 注意:回测中未完成订单会在当日结算时自动撤销,但在模拟交易或实盘中,
# 显式撤单是一个好的风控习惯,或者用于盘中策略逻辑控制。
run_daily(cancel_all_open_orders, '14:55')
def handle_data(context, data):
# 示例:每个单位时间随机下一个限价单(为了演示撤单)
# 实际策略中请替换为你的交易逻辑
current_price = data['000001.XSHE'].close
# 下一个很难成交的限价单(买入价为当前价的90%)
order('000001.XSHE', 100, style=LimitOrderStyle(current_price * 0.9))
def cancel_all_open_orders(context):
"""
自定义函数:查询并撤销所有未完成订单
"""
# 1. 获取当前所有未完成的订单
# 返回的是一个dict,key为order_id,value为Order对象
open_orders = get_open_orders()
if len(open_orders) > 0:
log.info("检测到 %d 个未完成订单,开始撤单..." % len(open_orders))
# 2. 遍历字典的 values (即 Order 对象)
for _order in open_orders.values():
# 3. 执行撤单
cancel_order(_order)
log.info("已撤销订单, 标的: %s, 订单ID: %s" % (_order.security, _order.order_id))
else:
log.info("当前没有未完成的订单。")
def after_trading_end(context):
log.info('盘后处理结束')
get_open_orders()order_id,Value 是 Order 对象。cancel_order(order)order,可以是 Order 对象,也可以是 order_id(字符串)。Order 对象;如果订单不存在或已完成,返回 None。Q: 为什么要显式调用撤单?回测不是会自动撤销吗?
A: 在回测环境中,每天收盘后系统确实会自动撤销未成交的订单。但在模拟交易或实盘中,或者在分钟级策略中(例如需要在当前分钟结束前撤销上一分钟的挂单),显式调用 cancel_order 是必须的,这有助于防止资金被无效挂单占用,或防止过期的信号在错误的时间成交。
Q: get_open_orders() 能获取到已经成交的订单吗?
A: 不能。它只返回状态为 open(已委托未成交)或 new(新创建未委托)的订单。如果订单已经全部成交(held)、已撤销(canceled)或被拒绝(rejected),不会包含在返回结果中。
Q: 如果我想撤销特定股票的订单怎么办?
A: 你可以在遍历时判断订单对象的 security 属性。例如:
orders = get_open_orders()
for _order in orders.values():
if _order.security == '000001.XSHE':
cancel_order(_order)