问题描述
解决方案
在 ptrade 量化交易平台中,使用 order_value(以及 order、order_target 等委托函数)时,如果遇到“限价价格异常”的报错,通常是由以下几个原因引起的。以下是详细的排查步骤和解决方法:
1. 价格精度(小数点位数)不符合品种要求
原因分析:
ptrade 对不同交易品种的价格精度有严格要求。如果传入的 limit_price 小数位数过多,柜台会拒绝接收,从而报错。
- 股票:价格精度为小数点后 2 位。
- 可转债、ETF、LOF:价格精度为小数点后 3 位。
- 股指期货:价格精度为小数点后 1 位。
解决方法:
在传入 limit_price 之前,务必使用 Python 的 round() 函数对价格进行精度处理。
def handle_data(context, data):
security = '600570.SS'
# 假设通过某种计算得到了一个价格
target_price = 45.12345
# 股票保留2位小数
valid_price = round(target_price, 2)
# 使用处理后的价格下单
order_value(security, 10000, limit_price=valid_price)
2. 未传入 limit_price 且行情快照获取失败
原因分析:
根据 ptrade API 文档,在交易场景下,如果调用 order_value(security, value) 时没有传入 limit_price 参数,系统会默认尝试获取该标的的**最新行情快照(最新价)**来进行报单。如果此时网络延迟、标的停牌或未订阅行情导致快照获取失败,系统无法确定委托价格,就会导致委托失败并提示价格异常。
解决方法:
- 方案 A:尽量显式传入
limit_price。可以通过get_snapshot或data[security]['close']自行获取价格,并增加异常判断。 - 方案 B:确保在
initialize中正确使用了set_universe订阅了该股票的行情。
def handle_data(context, data):
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:
# 确保精度正确
valid_price = round(last_px, 2)
order_value(security, 10000, limit_price=valid_price)
else:
log.warning(f"获取 {security} 最新价失败,放弃下单")
else:
log.warning(f"获取 {security} 行情快照失败")
3. 委托价格超出了涨跌停限制
原因分析:
如果传入的 limit_price 高于当日涨停价或低于当日跌停价,交易所会视为废单,部分券商柜台会直接拦截并提示价格异常。
解决方法:
在下单前,通过 get_snapshot 获取涨跌停价格,对委托价格进行边界限制(Clip)。
def handle_data(context, data):
security = '600570.SS'
target_price = 50.00 # 假设计算出的目标价
snapshot = get_snapshot(security)
if snapshot and security in snapshot:
up_px = snapshot[security].get('up_px', 9999)
down_px = snapshot[security].get('down_px', 0)
# 限制价格在跌停和涨停之间
target_price = max(down_px, min(target_price, up_px))
valid_price = round(target_price, 2)
order_value(security, 10000, limit_price=valid_price)
总结建议
为了提高策略的健壮性,建议封装一个安全的下单函数,将获取最新价、精度处理和涨跌停限制结合起来,避免直接调用裸接口引发报错。