🚀 AI 一键生成 joinquant 策略代码

JoinQuant 教程:如何查询未成交订单并进行撤单操作?

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

问题描述

如何查询我还没有成交的挂单,并且把它们取消掉?

解决方案

在 JoinQuant 聚宽平台中,查询未成交挂单并进行撤销的操作主要依赖于两个 API 函数:get_open_orders()cancel_order()

以下是具体的实现代码和详细说明。

代码实现

你可以将此逻辑封装在一个函数中,或者直接放在 handle_dataafter_trading_end 等函数中执行。

# -*- coding: utf-8 -*-

def cancel_open_orders(context):
    """
    查询并撤销所有未完成的挂单
    """
    # 1. 获取当前所有未完成的订单
    # 返回一个 dict, key 是 order_id, value 是 Order 对象
    orders = get_open_orders()
    
    # 判断是否有未完成订单
    if len(orders) > 0:
        log.info("发现未完成订单,准备撤单...")
        
        # 2. 遍历所有未完成的订单对象
        for _order in orders.values():
            # 3. 执行撤单操作
            cancel_order(_order)
            log.info("已撤销订单,订单ID: %s, 标的: %s" % (_order.order_id, _order.security))
    else:
        log.info("当前没有未完成的挂单。")

# 示例:在每天收盘后调用(需要在 initialize 中注册)
def after_trading_end(context):
    cancel_open_orders(context)

API 详解

1. get_open_orders()

  • 功能:获取当前账户所有未完成的订单(即挂单)。
  • 返回值:返回一个字典(dict)。
    • Key:订单 ID (order_id)。
    • Value:订单对象 (Order Object),包含订单的详细信息(如标的、数量、价格、状态等)。
  • 注意:该函数不需要传入参数。

2. cancel_order(order)

  • 功能:取消指定的订单。
  • 参数
    • order:可以是 Order 对象(推荐),也可以是订单 ID 字符串。
  • 返回值:如果撤单成功,返回对应的 Order 对象;如果订单不存在或已成交/已撤销,返回 None

使用场景建议

  1. 收盘后清理
    如上面的代码示例,通常在 after_trading_end 中调用,确保当天的挂单不会遗留到下一个交易日(虽然交易所通常会自动撤销当日未成交的普通委托,但在策略逻辑中显式撤单有助于保持状态清晰)。

  2. 下单前清理
    在使用 order_target(目标股数下单)系列函数前,如果希望重新调整仓位且不受旧挂单影响,可以先执行全额撤单。

  3. 策略逻辑触发
    例如在追涨杀跌策略中,如果挂单在 N 分钟内未成交,认为行情已经偏离预期,可以在 handle_data 中判断订单生成时间并进行撤单。


Q&A

Q: get_open_orders() 能获取到已经成交的订单吗?
A: 不能。它只返回状态为 open(已委托未成交)或 new(新创建未委托)的订单。如果订单已经全部成交(held)、已撤销(canceled)或被拒绝(rejected),不会包含在返回结果中。

Q: 如果我只想撤销某一只特定股票的挂单怎么办?
A: get_open_orders() 返回的是字典,你可以遍历它并判断 order.security 属性。例如:

orders = get_open_orders()
for _order in orders.values():
    if _order.security == '000001.XSHE': # 仅撤销平安银行的单子
        cancel_order(_order)

Q: 模拟交易和回测中,撤单的规则一样吗?
A: 基本一致。但在回测中,撤单是立即生效的;在模拟交易(实盘模拟)中,撤单请求发送给交易所后,需要等待交易所确认,存在极短的延迟。