问题描述
对某一笔订单做撤单时,撤成状态的成交主推只返回了100的委托数量,实际撤了1100股?
解决方案
在 ptrade 量化交易平台中,如果您在执行撤单操作时发现接收到的主推(on_trade_response 或 on_order_response)数量与实际撤单数量不一致(例如实际撤单1100股,但只收到100股的撤单主推),通常是由以下几个原因导致的:
1. 未开启接收撤单委托产生的主推
默认情况下,ptrade 策略是不接收撤单委托产生的主推的。如果您没有在策略初始化时显式开启该配置,可能会导致部分撤单主推信息丢失或接收不全。
解决方案:
在 initialize 函数中,使用 set_parameters 接口开启 receive_cancel_response 参数:
def initialize(context):
# 设置接收撤单委托产生的主推
set_parameters(receive_cancel_response="1")
2. 订单状态的异步更新与分批推送
柜台在处理撤单时,可能会根据当时的撮合情况将撤单结果分批推送。例如,1100股的撤单可能被拆分为一笔100股和一笔1000股的推送。如果策略逻辑在处理第一笔主推时发生了阻塞或异常,可能会导致后续的主推未能正确记录。
解决方案:
确保您的 on_trade_response 和 on_order_response 函数逻辑足够轻量,避免在主推回调中执行耗时的操作(如复杂的计算或同步的网络请求)。
3. 废单或价格笼子限制
如果您的原始委托中有部分数量因为触发了价格笼子或其他风控限制被直接标记为废单(status为9),这部分数量可能不会以常规的“撤单成功”状态推送给您。
解决方案:
在主推回调中,全面检查 status 字段。废单在委托回调(on_order_response)中的状态可能是 2(已报),但在成交回调(on_trade_response)中的状态会变为 9(废单)。
完整排查代码示例
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
# 关键配置:开启接收撤单主推和非本交易产生的主推
set_parameters(
receive_cancel_response="1",
receive_other_response="1"
)
def on_order_response(context, order_list):
for order in order_list:
log.info(f"委托主推 -> 订单号: {order.get('order_id')}, 状态: {order.get('status')}, 数量: {order.get('amount')}")
def on_trade_response(context, trade_list):
for trade in trade_list:
log.info(f"成交主推 -> 订单号: {trade.get('order_id')}, 状态: {trade.get('status')}, 成交/撤单数量: {trade.get('business_amount')}")
def handle_data(context, data):
pass
通过开启 receive_cancel_response="1" 并完整打印主推状态,您可以清晰地追踪到那缺失的1000股是处于“废单”状态还是分批推送的“已撤”状态。