3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在PTrade中,要实时跟踪订单的完整状态变化(如下单、部分成交、完全成交),最推荐且最高效的方式是使用 事件驱动的回调函数。
PTrade 提供了两个关键的回调接口:
on_order_response(context, order_list):委托主推。当订单状态发生变化(如变为“已报”、“部成”、“已成”、“废单”等)时,该函数会被立即触发。on_trade_response(context, trade_list):成交主推。当订单发生具体的成交动作(即有一笔撮合成功)时,该函数会被触发。相比于在 handle_data 中轮询 get_order(),使用这两个回调函数能以更低的延迟获取状态更新。
在处理回调数据时,需要关注 status 字段:
"2": 已报 (Submitted)"7": 部成 (Partial Filled) - 此时订单还有剩余数量未成交"8": 已成 (Filled) - 订单全部成交"9": 废单 (Rejected)"6": 已撤 (Canceled)"5": 部撤 (Partial Canceled)以下代码展示了如何下单,并通过回调函数实时打印订单从“已报”到“成交”的全过程日志。
def initialize(context):
"""
初始化函数
"""
# 设置股票池
g.security = '600570.SS'
set_universe(g.security)
# 用于记录我们关注的订单ID
g.my_order_id = None
# 标记是否已下单,防止重复下单
g.has_ordered = False
def handle_data(context, data):
"""
盘中运行函数
"""
# 仅为了演示:如果还没下单,且有行情,则下一个限价单
if not g.has_ordered:
# 获取当前价格
current_price = data[g.security]['close']
# 下单买入 1000 股,使用限价单(Limit Order)
# 注意:为了演示部分成交或成交过程,这里以当前价下单
g.my_order_id = order(g.security, 1000, limit_price=current_price)
if g.my_order_id:
log.info("【策略下单】下单成功,订单ID: %s,等待回调更新状态..." % g.my_order_id)
g.has_ordered = True
def on_order_response(context, order_list):
"""
委托主推回调:当订单状态发生变化时触发(如:已报、部成、已成、撤单等)
"""
for order_info in order_list:
# 过滤出我们自己下的那个订单
if order_info['order_id'] == g.my_order_id:
status = order_info['status']
entrust_no = order_info['entrust_no']
# 解析状态
status_desc = "未知状态"
if status == '2':
status_desc = "已报 (等待成交)"
elif status == '7':
status_desc = "部成 (部分成交,剩余待成交)"
elif status == '8':
status_desc = "已成 (全部成交)"
elif status == '9':
status_desc = "废单"
elif status == '6':
status_desc = "已撤"
elif status == '5':
status_desc = "部撤"
log.info("【委托状态更新】订单ID: %s, 委托编号: %s, 当前状态: %s (%s), 已成交数量: %s" % (
g.my_order_id,
entrust_no,
status,
status_desc,
order_info['business_amount']
))
# 如果完全成交,可以在这里做后续逻辑处理
if status == '8':
log.info(">>> 订单 %s 已全部完成,任务结束。" % g.my_order_id)
def on_trade_response(context, trade_list):
"""
成交主推回调:当发生具体成交动作时触发(比on_order_response更细节,关注每一笔撮合)
"""
for trade_info in trade_list:
# 过滤出我们自己下的那个订单
if trade_info['order_id'] == g.my_order_id:
log.info("【成交明细推送】订单ID: %s 发生一笔成交!成交数量: %s, 成交价格: %s, 成交金额: %s" % (
g.my_order_id,
trade_info['business_amount'],
trade_info['business_price'],
trade_info['business_balance']
))
handle_data 中下单后,我们将返回的 order_id 保存在全局变量 g.my_order_id 中,以便后续在回调中筛选。on_order_response (委托主推):
'2' (已报)。'7' (部成)。'8' (已成)。status 字段来打印对应的日志。on_trade_response (成交主推):
order_list 和 trade_list 中的元素是字典 (dict) 类型,而不是对象,因此访问属性时必须使用 ['key'] 的方式(如 order_info['status']),而不是 .status。get_order() 查询,适合高频或对时效性要求高的策略。Q: 为什么我在回测里看不到“部成”状态?
A: 回测引擎通常基于分钟线或日线撮合,假设流动性充足。除非您设置了严格的成交量限制(如 set_volume_ratio),否则小额订单通常会一次性完全成交,直接从状态 '2' 跳到 '8'。
Q: on_order_response 和 get_order() 有什么区别?
A: get_order() 是主动查询(轮询),通常在 handle_data 中调用,受限于策略运行频率(如每分钟一次)。on_order_response 是被动接收(推送),一旦柜台状态变化立即触发,延迟更低,且能捕获到中间状态。
Q: 如果我不使用回调,怎么查询订单状态?
A: 您可以在 handle_data 中使用 curr_order = get_order(g.my_order_id),然后检查 curr_order.status。但这只能获取调用那一刻的状态,可能会漏掉中间快速变化的过程。