🚀 AI 一键生成 joinquant 策略代码
立即体验

joinquant 撤单实战:如何使用 cancel_order 撤销盘中未成交订单?(附 Python 代码)

joinquant | 发布时间: 2026/7/30
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: joinquant 撤单实战:如何使用 cancel_order 撤销盘中未成交订单

Question: 如何在 joinquant 策略中获取当天的挂单并使用 cancel_order 进行撤单?

解决方案

joinquant 撤单实战:如何使用 cancel_order 撤销盘中未成交订单

在量化交易中,限价单可能因为价格波动未达到预期而未能及时成交。为了释放被挂单冻结的资金或仓位,我们需要在策略中对未成交订单进行管理与撤销。本文将详细介绍如何在 JoinQuant(聚宽)平台中使用 get_open_orders()cancel_order() 函数实现精准撤单。


1. 关键 API 介绍

1.1 获取未成交订单:get_open_orders()

用于获取当前交易日所有处于未完成状态(open / filled 部分成交)的订单。

  • 返回值:返回一个字典(dict),其中 key 为 order_id,value 为 Order 对象。

1.2 执行撤单:cancel_order(order)

用于取消指定的挂单。

  • 参数order,可以是 Order 对象或者订单 ID(order_id)。
  • 返回值:若取消成功则返回 Order 对象,订单不存在或已结束则返回 None

2. 常见撤单场景与代码实现

场景一:每日收盘后批量撤销所有未成交订单

after_trading_end(收盘后运行函数)中清理所有挂单:

import jqdata

def initialize(context):
    # 设置基准与复权
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    # 每日收盘后运行
    run_daily(after_market_close, time='15:30')

def after_market_close(context):
    # 1. 获取当前所有未完成订单
    open_orders = get_open_orders()
    
    # 2. 遍历并逐一撤单
    for order_id, order_obj in open_orders.items():
        cancel_result = cancel_order(order_obj)
        if cancel_result:
            log.info(f"收盘成功撤销订单: {order_id}, 标的: {order_obj.security}")

场景二:盘中超时未成交自动撤单

如果挂单超过一定时间未成交(例如买入单超过 10 分钟未撮合),可以通过记录订单时间进行超时撤单:

import jqdata

def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    # 每分钟检查一次挂单
    run_daily(check_and_cancel_timeout_orders, time='every_bar')

def check_and_cancel_timeout_orders(context):
    open_orders = get_open_orders()
    current_dt = context.current_dt
    
    for order_id, order_obj in open_orders.items():
        # 计算订单挂单时长(单位:秒)
        time_delta = (current_dt - order_obj.add_time).total_seconds()
        
        # 超过 600 秒(10分钟)未成交则撤单
        if time_delta > 600:
            cancel_order(order_obj)
            log.info(f"订单 {order_id} 挂单超时({time_delta}秒),已执行撤单")

3. 注意事项

  1. 系统自动撤单:聚宽回测/模拟盘会在每日交易日结束时自动撤销所有未完成订单(如 A 股在 17:00 之后),因此跨日策略无需担心昨日未成交订单影响次日开盘。
  2. 目标价值/股数下单函数的自动撤单:使用 order_targetorder_target_value 接口时,如果该标的当前已有未完成订单,系统会自动先取消之前未完成的订单再创建新订单。
  3. 挂单资金冻结:挂单未成交前会占用账户的 locked_cash(挂单锁住资金)或 locked_amount(挂单冻结仓位),撤单成功后资金或持仓会立即释放。