🚀 AI 一键生成 ptrade 策略代码

PTrade 高频交易核心:委托回报与成交回报函数的深度对比

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

问题描述

on_order_response 和 on_trade_response 这两个回调函数有什么区别?我应该用哪个来确认我的单子成交了?

解决方案

on_order_response 与 on_trade_response 的区别及用法

在 PTrade 量化交易系统中,on_order_response(委托主推)和 on_trade_response(成交主推)都是用于接收实时交易状态更新的回调函数,但它们的触发时机包含的数据侧重点完全不同。

1. 核心区别

特性 on_order_response (委托主推) on_trade_response (成交主推)
触发时机 委托状态发生任何变化时触发。包括:已报、废单、部成、已成、已撤等。 仅在发生实际成交时触发。包括:部分成交、全部成交。
关注对象 订单 (Order) 的生命周期。关注的是这张单子当前处于什么状态(是排队中、撤单了还是完成了)。 成交 (Trade) 的具体细节。关注的是刚刚那一笔撮合发生了什么(成交了多少股、成交价是多少)。
数据内容 包含委托编号、委托状态(status)、累计成交量、剩余撤销信息等。 包含成交编号、成交价格本次成交数量、成交金额等。
典型用途 监控订单是否报送成功、判断是否已全部完成、确认撤单是否成功。 计算实时的成交均价、统计刚刚买入/卖出的具体数量、做高频对冲逻辑。

2. 我应该用哪个来确认单子成交了?

如果你只是想确认**“我的单子有没有产生交易(成交)”**,最直接且推荐使用的是 on_trade_response

  • 推荐理由:该函数只有在撮合成功(买卖成交)时才会触发。只要收到了这个回调,就意味着资金和股票发生了交换。
  • 补充说明:如果你需要确认**“单子是否全部执行完毕(不再有剩余挂单)”**,则需要结合 on_order_response 中的 status 字段(状态为 '8' 代表已成)来判断。

3. 详细场景解析

场景 A:你需要知道刚刚那一笔成交了多少钱,用于计算成本

使用 on_trade_response
因为它返回的 trade_list 中包含 business_price(成交均价)和 business_amount(本次成交量),这是计算实时成本最准确的数据。

场景 B:你需要知道订单是否被废单,或者是否撤单成功

使用 on_order_response
on_trade_response 不会推送废单或撤单信息。你需要监听 on_order_response 中的 status

  • status == '9': 废单
  • status == '6': 已撤
  • status == '8': 已成(全部成交)

4. 代码示例

以下代码展示了如何同时使用这两个函数来监控交易状态:

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    # 必须在 initialize 中开启接收主推消息的参数(部分券商环境默认开启,显式设置更稳妥)
    # receive_other_response: 是否接收非本策略产生的订单主推
    set_parameters(receive_other_response="1")

def handle_data(context, data):
    # 示例:下单买入 1000 股
    order(g.security, 1000)

# 【委托主推】:用于监控订单状态变化(报单、撤单、全部完成)
def on_order_response(context, order_list):
    for order_info in order_list:
        # 获取订单状态
        status = order_info.get('status')
        entrust_no = order_info.get('entrust_no')
        
        if status == '8':
            log.info("订单 %s 已全部成交(Order Finished)" % entrust_no)
        elif status == '9':
            log.error("订单 %s 是废单,请检查资金或参数(Order Rejected)" % entrust_no)
        elif status == '6':
            log.info("订单 %s 已撤单(Order Canceled)" % entrust_no)
        elif status == '2':
            log.info("订单 %s 已报送至柜台(Order Submitted)" % entrust_no)

# 【成交主推】:用于确认具体的成交动作(最适合确认“成交了”)
def on_trade_response(context, trade_list):
    for trade_info in trade_list:
        stock_code = trade_info.get('stock_code')
        price = trade_info.get('business_price')
        amount = trade_info.get('business_amount')
        entrust_no = trade_info.get('entrust_no')
        
        # 只要进到这里,说明肯定发生了成交
        log.info(">>> 确认成交!股票: %s, 委托号: %s, 本笔成交价: %f, 本笔成交量: %f" % (
            stock_code, entrust_no, price, amount
        ))

Q&A 常见问题解答

Q: 如果一个大单分成了 5 笔成交,这两个函数会触发几次?

  • on_trade_response: 会触发 5次。每一笔撮合成功都会推送一次,告诉你这一笔成交了多少。
  • on_order_response: 可能会触发 5次或更多。每次成交后,订单的“累计成交量”发生变化,状态可能从“已报”变为“部成”(部分成交),最后变为“已成”。它反映的是订单状态的更新。

Q: on_order_response 里的 amounton_trade_response 里的 business_amount 有什么区别?

  • on_order_response 中的 amount 通常指委托总数量(或者是该订单当前的累计成交数量,视具体字段定义而定,通常需结合 business_amount 字段看累计值)。
  • on_trade_response 中的 business_amount 指的是当前这一笔的成交数量(增量)。

Q: 回测模式下这两个函数有用吗?

  • 有用。PTrade 的回测引擎会模拟撮合过程。虽然回测通常是基于分钟或日线数据,但在回测中这两个函数依然会被调用,逻辑与实盘一致,非常适合用来验证策略的信号处理逻辑。