问题描述
量化进行交易后,交易日志打印交易成功,但是在查询内委托流水无记录。
解决方案
在 ptrade 量化交易平台中,遇到“日志打印交易成功,但委托流水无记录”的情况,通常是因为对“下单成功”的理解存在偏差,或者订单在报送柜台后被拒单。以下是详细的排查指南和解决方案:
1. 核心原因:订单成为了“废单”
在 ptrade 中,调用 order() 等下单函数后,如果返回了一个 order_id(订单编号),仅代表量化引擎成功接收了该下单请求,并不代表柜台已经接受或成交。
如果你的委托价格不合规(例如:超出了涨跌停限制、触发了全面注册制下的“价格笼子”机制),柜台会直接拒单,该订单会变成废单。废单在某些终端的常规委托流水中可能默认不显示,或者你需要专门查询废单记录。
官方文档提示:
如果是废单,如下单价格超过价格笼子,order函数依然会返回order_id,而不是None,并且在委托回调函数里面的状态status是2(已报),但在成交回调里面的status是9(废单)。
2. 常见导致废单的原因
- 价格精度错误:股票价格必须是小数点后两位,可转债、ETF、LOF 是小数点后三位。如果传入了未处理精度的小数(如
10.123买股票),会导致委托失败。 - 资金或持仓不足:虽然引擎有校验,但在某些极端并发或极速行情下,柜台校验资金/持仓不足会直接拒单。
- 非交易时间下单:在非交易时间(如午休)下了不支持的单子。
3. 排查与解决步骤
步骤一:通过代码主动查询订单状态
不要仅凭 order() 返回了 ID 就认为成功,应该使用 get_order() 或 get_orders() 检查该订单的最终 status。
def handle_data(context, data):
order_id = order('600570.SS', 100)
if order_id:
# 获取订单详情
order_info = get_order(order_id)
if order_info:
status = order_info[0].status
log.info(f"订单 {order_id} 的当前状态为: {status}")
if status == '9':
log.error("订单成为废单,请检查价格是否超出笼子或精度是否正确!")
(注:状态 9 代表废单,8 代表已成)
步骤二:使用主推回调实时监控废单
建议在策略中加入 on_trade_response 或 on_order_response 函数,实时捕获订单状态变化,特别是废单状态。
def on_trade_response(context, trade_list):
for trade in trade_list:
if trade.get('status') == '9':
log.error(f"发现废单!股票:{trade.get('stock_code')},委托编号:{trade.get('entrust_no')}")
步骤三:检查查询 API 的使用
如果你是在代码中查询流水发现无记录,请确认你使用的 API 是否正确:
get_trades():只返回当日已成交的订单。如果订单是废单或未成交,这里查不到。get_all_orders():返回账户当日全部订单(包含废单)。你可以打印这个接口的返回值来确认订单是否真的不存在。
总结
“日志打印成功”通常只是代码执行通过,请务必:
- 检查下单价格是否符合价格笼子和涨跌停限制。
- 检查价格小数点精度是否符合品种要求。
- 打印
get_order(order_id)[0].status,确认是否为9(废单)。