问题描述
解决方案
在 PTrade 中,order 函数本身返回的是订单编号(Order ID)(字符串类型),而不是直接返回完整的订单对象。
要查看订单的详细信息(如成交量、状态等),你需要使用 get_order(order_id) 函数,它会返回一个 Order 对象。
以下是关于 Order 对象包含的信息以及如何判断成交的详细说明。
1. Order 对象包含的信息
当你通过 get_order(order_id) 获取到对象后,它包含以下主要属性:
| 属性名 | 类型 | 说明 |
|---|---|---|
| id | str | 订单编号(即 order 函数的返回值) |
| symbol | str | 标的代码(例如 '600570.SS') |
| amount | int | 下单数量(正数代表买入,负数代表卖出) |
| filled | int | 成交数量(买入为正,卖出为负)。这是判断成交量的关键字段。 |
| status | str | 订单状态。这是判断订单当前情况的关键字段。 |
| limit | float | 指定价格(限价单的价格,市价单可能为 None 或 0) |
| entrust_no | str | 委托编号(柜台返回的编号) |
| created | datetime | 订单生成时间 |
| priceGear | str | 盘口档位(如下单时指定) |
2. 如何判断单子有没有成交?
主要有两种方式来判断订单的成交情况:
方法一:检查 status(订单状态)字段
status 是一个字符串,不同的数字代表不同的状态。最常用的状态码如下:
- '8':已成(全部成交)
- '7':部成(部分成交)
- '2':已报(已报送交易所,但尚未成交)
- '6':已撤(订单已撤销)
- '9':废单(订单无效)
判断逻辑:
- 如果
status == '8',说明全部成交。 - 如果
status == '7',说明部分成交。
方法二:检查 filled(成交数量)字段
你可以直接对比 filled(已成交数量)和 amount(下单总数量)。
判断逻辑:
- 如果
filled != 0,说明有成交(可能是部分成交,也可能是全部成交)。 - 如果
abs(filled) == abs(amount),说明全部成交。
3. 代码示例
以下代码展示了如何下单、获取订单对象、打印详细信息以及判断是否成交。
def initialize(context):
# 设置股票池
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 1. 下单,并获取订单ID
# 注意:order返回的是字符串ID,不是对象
order_id = order(g.security, 100)
if order_id is None:
log.info("下单失败")
return
# 2. 通过ID获取完整的 Order 对象
# 注意:get_order 返回的是一个列表,通常取第一个元素
order_obj_list = get_order(order_id)
if order_obj_list:
current_order = order_obj_list[0]
# 3. 打印订单对象里的主要信息
log.info("订单编号: %s" % current_order.id)
log.info("标的代码: %s" % current_order.symbol)
log.info("下单数量: %s" % current_order.amount)
log.info("成交数量: %s" % current_order.filled)
log.info("订单状态码: %s" % current_order.status)
# 4. 判断成交情况
if current_order.status == '8':
log.info("【成交提醒】订单已全部成交!")
elif current_order.status == '7':
log.info("【成交提醒】订单部分成交,当前成交量:%s" % current_order.filled)
elif current_order.status == '2':
log.info("【状态提醒】订单已报送,等待成交中...")
elif current_order.status == '9':
log.info("【废单提醒】订单被拒绝,请检查资金或持仓。")
# 也可以通过 filled 字段判断
if abs(current_order.filled) == abs(current_order.amount):
log.info("通过数量校验:已全额成交")
4. 注意事项
- 回测与实盘的区别:
- 在回测中,
order下单后,通常在同一个handle_data周期内或下一个周期就能看到成交结果(取决于回测机制和撮合逻辑)。 - 在实盘中,成交是异步的。下单后立即调用
get_order可能状态还是“未报”或“待报”。你可能需要在后续的handle_data轮询,或者使用on_order_response(委托回报)和on_trade_response(成交回报)回调函数来实时接收成交信息。
- 在回测中,
- get_order 返回值:
get_order(order_id)返回的是一个列表[Order],所以通常需要使用[0]来获取具体的对象。
Q&A
Q: 为什么我调用 order 后立即打印 filled 字段是 0?
A: 在实盘交易中,下单到交易所撮合需要时间。代码执行速度很快,当你刚下完单立即查询时,订单可能还在传输中或排队中,尚未成交。建议在后续的时间切片中查询,或使用 on_trade_response 回调函数。
Q: status 状态码 '5' 和 '6' 有什么区别?
A: '6' 代表“已撤”,即订单被完全撤销,没有剩余待成交部分。'5' 代表“部撤”,即订单在部分成交后,剩余未成交的部分被撤销了。
Q: 如何获取当天所有的订单信息?
A: 可以使用 get_orders()(获取策略内的订单)或 get_all_orders()(仅交易模式可用,获取账户当日所有订单,包括非策略下单的)。