问题描述
解决方案
在ptrade量化交易平台的实盘环境中,使用 order、order_target、order_value、order_target_value 等委托接口时,如果遇到行情获取失败导致委托失败的情况,通常是因为参数设置或行情接口调用机制引起的。以下是详细的原因分析及解决方案:
一、 原因分析
根据ptrade API文档规定:在交易场景中,如果 limit_price 字段不入参,系统会默认用行情快照数据(get_snapshot)的最新价进行报单。
假如当时网络波动、接口限流或该标的无实时行情,导致行情快照获取失败,系统就无法获取到默认的委托价格,从而导致委托失败,系统会在日志中增加相应的警告提醒。
二、 解决方案
为了提高实盘策略的健壮性,建议采取以下几种解决方案:
1. 显式传入 limit_price 参数(推荐)
最直接有效的避免方法是:永远不要省略 limit_price 参数。在调用下单接口前,先通过其他方式(如 get_history、get_snapshot 或 get_gear_price)获取价格,并进行有效性校验,然后再传入下单接口。
def handle_data(context, data):
security = '600570.SS'
# 方案A:从 data 中获取最新价(适用于 handle_data 盘中)
if security in data:
current_price = data[security]['close']
if current_price > 0:
order(security, 100, limit_price=current_price)
log.info(f"下单成功,委托价:{current_price}")
2. 手动获取快照并增加异常处理
如果策略不在 handle_data 中运行(例如在 run_daily 或 run_interval 中),可以手动调用 get_snapshot,并判断返回值是否为空或价格是否为0。
def interval_handle(context):
security = '600570.SS'
snapshot = get_snapshot(security)
# 校验快照数据是否获取成功
if snapshot and security in snapshot:
last_px = snapshot[security].get('last_px', 0)
if last_px > 0:
# 明确传入 limit_price
order_target(security, 100, limit_price=last_px)
else:
log.warning(f"{security} 最新价为0,放弃下单")
else:
log.error(f"获取 {security} 行情快照失败,请检查网络或接口状态")
3. 使用市价委托接口 order_market
如果您的策略对滑点不敏感,且交易标的支持市价单(如上交所、深交所的部分股票),可以使用 order_market 接口直接以市价委托,这样就不需要依赖系统去获取最新价作为限价单的价格。
def handle_data(context, data):
security = '600570.SS'
# 使用最优五档即时成交剩余转限价 (market_type=1)
order_market(security, 100, market_type=1)
三、 注意事项
- 价格精度问题:传入
limit_price时,请注意不同品种的价格精度。股票通常为2位小数,可转债、ETF、LOF为3位小数。如果精度错误,也可能导致柜台拒单。 - 涨跌停限制:在自行计算
limit_price时,建议结合check_limit接口判断标的是否已经涨跌停,避免无效废单。 - 避免重复下单:在使用
order_target系列接口时,如果因为行情失败导致逻辑重试,请务必结合get_orders或get_position检查在途委托,防止重复下单。