问题描述
Ptrade成交回调函数无法执行的原因? | ptrade bug
目前的ptrade有一个隐藏很深的bug。
就是回调函数里面有一个字段entrust_no.
这个字段是什么意思呢? 是营业部的下单编号。比如你挂了一个委托单,就会有一个entrust_no, 比如 100001
这个编号对于一天的数据来说,是唯一不重复的,也就是一天内再不会出现100001。
而ptrade的成交回调依赖的是这个entrust_no, 如果系统里面已经触发过了一个entrust_no 为 100001的成交委托,那么如果又有一个重复的订单entrust_no 100001成交,那么,此时的ptrade的 成交回调函数是不会触发的!
那么上面说的一天内这个entrust_no是不会重复的。
可是,这个entrust_no挂单编号,在同一个营业部单元里,第二天会重复的,比如你第二天挂单也是entrust_no 100001,并且你的ptrade策略没有重启,也就是一直运行的话,那么如果碰巧你的下单entrust_no上昨天或者之前某一天(ptrade策略没有重启开始算起),entrust_no重复了的情况下。
此时的ptrade 成交回调函数 on_trade_repsonse 是不会执行的!!!
天坑!
解决方案
Ptrade 成交回调函数 (on_trade_response) 无法执行的隐藏 Bug 解析\n\n在 Ptrade 量化交易平台中,许多高频或对执行速度要求较高的策略会依赖 on_trade_response(成交主推回调函数)来处理订单成交后的逻辑。然而,部分开发者发现该函数在某些情况下会神秘失效。这实际上与 Ptrade 底层对 entrust_no(委托编号)的处理机制有关。\n\n### 1. Bug 的核心原因:entrust_no 跨日重复\n\n* 什么是 entrust_no?\n entrust_no 是营业部柜台生成的下单编号(例如 100001)。在同一个交易日内,这个编号是绝对唯一且不重复的。\n* Ptrade 的回调机制缺陷\n Ptrade 的底层引擎在触发 on_trade_response 时,会记录并依赖这个 entrust_no。如果系统检测到某个 entrust_no 已经触发过成交回调,为了防止重复推送,它可能会忽略后续相同编号的推送。\n* 触发 Bug 的场景\n entrust_no 仅在单日内唯一,第二天柜台的编号会重置。如果你的 Ptrade 策略跨日连续运行(没有重启),且第二天的某个订单碰巧分配到了与昨天(或之前某天)相同的 entrust_no,Ptrade 引擎会误认为这是一笔“已经处理过的旧订单”,从而拒绝触发 on_trade_response。\n\n### 2. 解决方案与规避建议\n\n既然这是一个底层机制导致的“天坑”,在官方修复此 Bug 之前,量化开发者可以通过以下几种方式进行规避:\n\n#### 方案一:每日定时重启策略(最推荐)\n这是最简单且最彻底的规避方法。由于 Bug 的触发前提是“策略跨日连续运行导致内存中缓存了历史的 entrust_no”,只要每天盘前重启策略,引擎的缓存就会被清空。\n* 操作建议:在券商服务器或本地客户端中,设置每日盘后或盘前(如 8:30)自动重启 Ptrade 客户端及策略。\n* 注意:重启时请配合 pickle 模块做好全局变量 g 的持久化保存,以免丢失持仓或状态数据。\n\n#### 方案二:降级使用主动轮询机制 (get_trades)\n如果你的策略不能重启,或者对毫秒级延迟要求不是极高,可以放弃使用主推回调,改用主动查询。\n* 实现方式:在 handle_data 或 run_interval 中,定时调用 get_trades() 接口获取当日成交记录。\n* 代码示例:\npython\ndef run_interval_func(context):\n trades = get_trades()\n if trades:\n # 遍历并处理未处理的成交记录\n pass\n\n\n#### 方案三:依赖 order_id 而非 entrust_no\n在 Ptrade 中,order_id 是由 Ptrade 引擎生成的 UUID(如 e71d1684c8a74b4ca00b3326c9eb8614),它是全局唯一的,永远不会重复。\n* 虽然主推回调可能不触发,但你可以通过 get_orders() 或 get_open_orders() 轮询订单状态,通过比对 order_id 的 status 字段(如状态变为 '8' 已成)来判断订单是否成交。\n\n### 总结\nPtrade 的 on_trade_response 跨日失效是一个典型的状态缓存未清理导致的 Bug。在编写实盘策略时,强烈建议养成每日重启交易环境的习惯,这不仅能规避 entrust_no 重复的问题,还能有效释放内存,保持策略运行的稳定性。