问题描述
进行量化 交易后,委托状态返回一直都是0,但是策略是使用的tick_data每3秒查询返回!
解决方案
在 ptrade 量化交易平台中,订单的 status 字段返回 0 代表该订单的状态为 “未报”(即订单已在本地生成,但尚未成功报送到券商柜台或交易所)。
如果您在使用 tick_data(每3秒运行一次)时发现委托状态一直停留在 0,通常是由以下几个原因导致的。以下是详细的排查方向与解决方案:
1. 频繁重复下单导致查询错位(最常见)
tick_data 函数每3秒触发一次。如果您在 tick_data 中编写了下单逻辑,但没有使用全局变量(如 g.flag)进行状态控制,策略会每隔3秒就下达一笔新订单。当您去查询订单状态时,可能查到的永远是刚刚生成、还未来得及报送的“最新一笔”订单,从而导致看到的永远是 0。
解决方案:在下单逻辑中加入控制标识,确保同一信号只触发一次委托。
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
g.has_ordered = False # 增加下单控制标识
def tick_data(context, data):
if not g.has_ordered:
# 满足条件后下单
order_tick(g.security, 100, limit_price=40.00)
g.has_ordered = True # 下单后立即锁定,防止3秒后重复下单
2. 轮询查询存在延迟,建议改用主推回调
虽然 tick_data 每3秒执行一次,但主动调用 get_orders() 或 get_order() 去轮询订单状态并不是最高效的做法。在订单刚发出的极短时间内,状态确实是 0。
解决方案:ptrade 提供了专门的委托主推事件 on_order_response。该函数会在订单状态发生变化(如从“未报”变为“已报”、“部成”、“已成”等)时瞬间自动触发,速度远快于 tick_data 轮询。
def on_order_response(context, order_list):
for order in order_list:
log.info("委托单号: %s, 当前状态: %s" % (order['entrust_no'], order['status']))
if order['status'] == '8':
log.info("订单已完全成交!")
elif order['status'] == '9':
log.info("订单为废单,请检查价格或资金!")
3. 在非交易时间段下单
如果您在盘前(如 9:15 - 9:25 之间,或者中午休市期间)下达了非集合竞价支持的订单,订单会被 ptrade 引擎接收,但柜台可能暂不受理,此时状态会一直保持为 0(未报)或 1(待报),直到开盘后才会推送到交易所。
解决方案:确保下单动作发生在连续竞价交易时间段(9:30-11:30, 13:00-14:57)。可以使用 get_snapshot 获取 trade_status 字段,确保其为 'TRADE'(连续撮合交易状态)时再下单。
4. 价格精度或参数不合规导致被本地拦截
ptrade 对不同品种的价格精度有严格要求:
- 股票:小数点后 2 位
- 可转债、ETF、LOF:小数点后 3 位
如果传入的价格小数位数过多(例如 39.1234 买入股票),或者买入数量不符合规则(如股票买入不是100的整数倍),订单可能会在本地校验时失败,停留在“未报”状态,甚至直接转为废单。
解决方案:在下单前对价格进行 round(price, 2) 处理。
总结建议
针对您的场景,建议将**“下单逻辑”保留在 tick_data 中(并加好 g.flag 防重),而将“状态查询逻辑”**转移到 on_order_response 中。这样既能利用 tick 级别的高频行情捕捉交易机会,又能最实时、准确地获取订单的真实状态。