问题描述
/
解决方案
核心解答
默认情况下不会,但可以通过代码配置开启捕获。
在 ptrade 平台上,如果策略A和策略B同时运行在同一个资金账户下,默认情况下,策略B的 on_order_response(委托主推)和 on_trade_response(成交主推)只会捕获策略B自己产生的交易事件。
但是,ptrade 提供了接收“非本交易产生的主推”的功能。如果你希望策略B能够捕获到策略A(或手动在终端下的单)的成交回调,需要在策略B中进行特定配置。
如何让策略B捕获策略A的回调?
你需要在策略B的 initialize 或 before_trading_start 函数中,使用 set_parameters 接口开启接收其他响应的开关:
set_parameters(receive_other_response="1")
receive_other_response="0":不接收非本交易产生的主推(缺省默认值)。receive_other_response="1":接收非本交易产生的主推。
捕获到的数据有什么特征?
当策略B开启了 receive_other_response="1" 后,它在 on_trade_response 中接收到策略A的成交数据时,会有一个非常明显的特征:
由于该订单不是由策略B的引擎发出的,策略B的上下文中没有对应的 Order 对象,因此主推信息字典中的 order_id 字段会被赋值为空字符串 ""。
数据格式对比:
- 本策略(策略B自己)产生的主推:
[{'status': '8', 'business_amount': 200, 'order_id': 'e71d1684c8a74b4ca00b3326c9eb8614', 'entrust_no': 700006, ...}] - 非本策略(策略A或手动下单)产生的主推:
[{'status': '8', 'business_amount': 200, 'order_id': '', 'entrust_no': 700007, ...}]
策略B的代码示例
以下是策略B如何配置并区分处理自身订单和策略A订单的示例代码:
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
# 关键配置:设置接收非本交易产生的主推
set_parameters(receive_other_response="1")
def on_trade_response(context, trade_list):
for trade in trade_list:
if trade['order_id'] == "":
log.info("【策略B捕获】检测到非本策略(如策略A)的成交!委托编号: %s, 成交量: %s" % (trade['entrust_no'], trade['business_amount']))
# 在这里编写针对策略A成交后的联动逻辑
else:
log.info("【策略B捕获】本策略自身的成交!订单ID: %s" % trade['order_id'])
def handle_data(context, data):
pass
⚠️ 重要注意事项
- 券商配置前提:接收非本交易产生的主推,前提是券商后台配置了允许推送全局主推数据。部分券商为了减轻服务器压力,默认在底层关闭了全局推送。如果设置了
receive_other_response="1"依然收不到,请联系所在券商的 ptrade 技术支持确认是否开启了该权限。 - 避免死循环:如果在
on_trade_response中捕获到策略A的成交后,策略B又立即调用order()下单,极易引发逻辑上的无限迭代循环,编写联动策略时务必增加状态锁(如全局变量 flag)进行控制。 - 撤单主推:同理,如果想捕获策略A的撤单事件,还需要配置
set_parameters(receive_cancel_response="1")。