问题描述
量化进行交易后,交易日志打印交易成功,但是在查询内委托流水无记录。
解决方案
在ptrade量化交易平台中,如果遇到“日志打印交易成功,但在委托流水中查无记录”的情况,通常是由于API接口使用差异、订单状态变为废单、或者柜台数据同步延迟等原因引起的。以下是详细的排查步骤和解决方法:
1. 确认是否为“废单”(最常见原因)
在ptrade中,调用 order() 等下单函数时,只要语法正确且成功发送到系统,就会返回一个 order_id。很多开发者会在此时打印“交易成功”。但是,返回 order_id 并不代表柜台已经撮合成交,甚至不代表柜台接受了该订单。
- 原因:如果下单价格超过价格笼子、资金不足、或者没有可卖持仓,柜台会将其标记为废单(status='9')。
- 排查方法:使用
get_order(order_id)检查该订单的真实状态。
def handle_data(context, data):
order_id = order('600570.SS', 100)
if order_id:
log.info('下单请求已发送,order_id: %s' % order_id)
# 检查订单真实状态
order_obj = get_order(order_id)
if order_obj and order_obj[0].status == '9':
log.error('订单被柜台拒单,成为废单!')
2. 区分 get_orders() 与 get_all_orders()
如果你是通过代码查询委托流水发现无记录,请检查你使用的是哪个查询接口:
get_orders():仅返回当前策略内产生的订单。如果你在其他策略或手动进行了交易,这里查不到。get_all_orders():返回账户当日在柜台的全部委托记录(包含非本交易/手动产生的订单记录)。- 建议:在实盘交易中,使用
get_all_orders()来确认账户层面的真实委托流水。
3. 柜台数据同步延迟
在实盘交易场景中,持仓和委托信息的同步存在时滞(一般在6秒左右,具体由券商柜台配置决定)。
- 现象:下单后立即调用
get_orders()或get_open_orders(),可能因为数据尚未从柜台同步回来而查不到记录。 - 解决方法:不要在下单后立刻进行轮询查询。建议使用委托主推事件
on_order_response和 成交主推事件on_trade_response来异步接收订单状态更新,这比主动查询速度更快且更准确。
def on_order_response(context, order_list):
# 当委托单发生变化时,系统会主动推送到这里
log.info('收到委托主推更新: %s' % order_list)
4. 检查是否使用了 order_target 或 order_target_value
API文档中特别指出,在交易场景中应谨慎使用 order_target 系列接口。因为柜台返回持仓数据有延迟,如果连续触发 order_target,引擎可能因为没读到最新的持仓而导致重复下单或逻辑错乱,最终可能被柜台拒单。
5. 回测与实盘的机制差异
- 回测环境:每天结束时,系统会自动取消所有未完成的交易。如果你的订单挂单价格不合理,一天都没成交,盘后查询自然没有成交记录。
- 实盘环境:请确保你的价格精度正确(如股票是2位小数,可转债/ETF是3位小数)。如果传入了错误精度的小数,可能会导致委托直接失败。
总结建议:
将你的“交易成功”日志打印逻辑,从“下单函数返回后打印”修改为“在 on_trade_response 或 on_order_response 中判断状态为已成(status='8')后打印”,这样就能确保日志与实际委托流水完全一致。