🚀 AI 一键生成 joinquant 策略代码

JoinQuant 高效订单管理:如何使用 batch_cancel_orders 批量撤销未成交订单?

joinquant | 发布时间: 2025/12/15
以下内容由 EasyQuant 生成。

问题描述

我的策略会挂很多限价单,收盘前如何快速把所有没成交的单子都撤掉?

解决方案

在聚宽(JoinQuant)中,要实现收盘前快速撤销所有未成交订单,可以使用 get_open_orders() 获取当前未完成订单,配合 batch_cancel_orders() 进行批量撤单。

为了确保在收盘前执行,通常会在 initialize 中使用 run_daily 设置一个定时任务(例如 14:55)。

以下是具体的实现代码:

# -*- coding: utf-8 -*-
def initialize(context):
    # 设置基准等其他初始化代码...
    set_benchmark('000300.XSHG')
    
    # 设定每天收盘前(例如14:55)执行撤单函数
    # time参数可以根据需要调整,如 '14:50', '14:58' 等
    run_daily(cancel_all_open_orders, '14:55')

def cancel_all_open_orders(context):
    """
    撤销所有未完成订单的函数
    """
    # 获取当前所有未完成的订单,返回一个dict,key为order_id,value为Order对象
    open_orders = get_open_orders()
    
    if len(open_orders) > 0:
        # 将字典的值转换为列表,因为batch_cancel_orders接收列表
        orders_list = list(open_orders.values())
        
        # 使用批量撤单函数,比循环调用 cancel_order 效率更高
        batch_cancel_orders(orders_list)
        
        log.info("收盘前批量撤销了 %d 个未完成订单" % len(orders_list))
    else:
        log.info("收盘前检查:当前没有未完成订单")

# 示例:模拟盘中下单(仅为了演示撤单功能,实际策略中不需要这部分)
def handle_data(context, data):
    # 每天9:30挂一个很难成交的单子用于测试
    if context.current_dt.hour == 9 and context.current_dt.minute == 30:
        # 以跌停价买入平安银行,通常不会立即成交,会挂在订单簿上
        current_price = data['000001.XSHE'].close
        order('000001.XSHE', 100, style=LimitOrderStyle(current_price * 0.9))

代码说明:

  1. get_open_orders(): 获取当前账户所有状态为 open(已委托未成交)或 new(新创建未委托)的订单。
  2. batch_cancel_orders(orders_list): 这是处理“很多限价单”的关键。相比于写 for 循环逐个调用 cancel_order,批量撤单接口在处理大量订单时速度更快,且能减少日志输出的冗余。
  3. run_daily(func, time='14:55'): 确保撤单逻辑在收盘前的特定时间点自动触发。建议时间不要设置得离 15:00 太近(如 14:59:59),以免因系统延迟导致撤单失败。

Q&A

Q: batch_cancel_orders 和循环调用 cancel_order 有什么区别?
A: 功能上是一样的,都是撤单。但是当挂单数量较多时,batch_cancel_orders 是专门优化的批量接口,执行效率更高,且不会像循环调用那样产生大量的单条撤单日志,更适合高频或多网格策略。

Q: 如果我在 14:55 撤单后,策略逻辑在 14:57 又触发了下单怎么办?
A: 如果您的策略逻辑(如 handle_data)在撤单时间点之后还会运行并产生信号,新订单依然会发出。如果您希望收盘前彻底停止交易,可以在撤单函数中设置一个全局标志位(如 g.stop_trading = True),并在下单逻辑中检查这个标志位。

Q: 只有股票策略可以使用这个方法吗?
A: 不仅是股票,期货、基金等策略均适用此方法。对于期货策略,注意区分夜盘和日盘的收盘时间。