🚀 AI 一键生成 joinquant 策略代码

JoinQuant API 进阶:如何使用 Order 和 Trade 对象进行精细化交易分析?

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

问题描述

下单后,我如何获取这笔订单的详细成交信息,比如最终的成交均价和手续费?

解决方案

在 JoinQuant(聚宽)中,当你调用下单函数(如 orderorder_targetorder_value 等)时,这些函数会返回一个 Order 对象

你可以通过访问这个 Order 对象的属性来获取成交均价、手续费等详细信息。

核心属性说明

  • order.price: 成交均价。即该笔订单所有成交部分的平均价格。
  • order.commission: 交易费用。包含佣金和印花税等。
  • order.filled: 已成交数量
  • order.status: 订单状态。例如 OrderStatus.held (全部成交)、OrderStatus.filled (部分成交) 等。

代码示例

以下是一个完整的策略示例,展示了如何在下单后立即打印出成交均价和手续费:

# -*- coding: utf-8 -*-
from jqdata import *

def initialize(context):
    # 设置基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 设置手续费(示例:股票买入万三,卖出万三加千一印花税,最低5元)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 每天开盘时运行
    run_daily(market_open, time='09:30')

def market_open(context):
    security = '000001.XSHE' # 平安银行
    
    # 下单买入 1000 股
    # order 函数会返回一个 Order 对象
    current_order = order(security, 1000)
    
    # 判断订单是否创建成功(如果股票停牌或资金不足可能返回 None)
    if current_order is not None:
        # 打印订单对象,查看概览
        log.info("订单创建成功,订单ID: %s" % current_order.order_id)
        
        # 如果是回测环境(市价单通常立即成交),可以直接获取成交信息
        # 注意:在模拟交易或分钟回测中,建议判断 order.filled > 0
        if current_order.filled > 0:
            log.info("=" * 30)
            log.info("【成交详情】")
            log.info("标的代码: %s" % current_order.security)
            log.info("成交数量: %d" % current_order.filled)
            log.info("成交均价: %.2f" % current_order.price)
            log.info("交易费用: %.2f" % current_order.commission)
            log.info("=" * 30)
        else:
            log.info("订单尚未成交")
    else:
        log.info("订单创建失败")

# 收盘后也可以查询当天的所有成交记录
def after_trading_end(context):
    log.info("--- 收盘后查询当日成交 ---")
    # get_trades() 获取当天的所有成交记录
    trades = get_trades()
    for trade_id, trade in trades.items():
        log.info("订单ID: %s, 成交价: %.2f, 数量: %d" % (trade.order_id, trade.price, trade.amount))

注意事项

  1. 市价单与限价单的区别

    • 回测中:市价单通常会立即成交(除非跌停或停牌),返回的 Order 对象中 pricecommission 已经有值。
    • 限价单:下单瞬间可能未成交。此时 order.filled 为 0,order.price 可能为 0 或初始值。你需要通过 get_orders() 在后续的时间点(如 handle_data 的下一次调用中)查询该订单的状态更新。
  2. 查询历史订单
    如果你没有保存下单时的返回值,也可以使用 get_orders(order_id='xxx') 通过订单ID重新获取该对象。

  3. 分笔成交
    如果一个订单分多次成交(例如下了1000股,分两次各成交500股),Order.price 会自动计算为这1000股的加权平均价Order.commission 会是总手续费。如果你需要每一笔细分的成交记录,请使用 get_trades()


Q&A

Q: 如果我使用的是限价单(LimitOrder),下单函数返回的 Order 对象里会有成交价吗?
A: 如果限价单没有立即成交(例如挂单价格远低于当前价),返回的 Order 对象中 filled 为 0,price 通常为 0。你需要等待订单成交后,再次获取该订单对象(通过 get_orders())来查看最终的成交均价。

Q: order.priceorder.avg_cost 有什么区别?
A: 在买入订单中,priceavg_cost 通常是一样的,都代表本次买入的均价。但在卖出订单中,price 是本次卖出的成交均价,而 avg_cost 是卖出前该股票的持仓成本(用于计算收益)。

Q: 如何获取某只股票当天的所有成交记录?
A: 可以使用 get_trades() 函数获取当天的所有成交记录,然后遍历返回的字典,通过 trade.security 属性筛选出特定股票的成交记录。