问题描述
ERROR - 订单委托失败:MarginOrder(entrust_id=1592901116 security=600740.XSHG mode=OrderAmount: _amount=190260 style=MarketOrderStyle: _limit_price=0.0 side=long action=open margin=False entrust_time=2010-04-01 09:30:00 error=),如题,这里显示订单委托失败,但是error=后面没有任何内容了,这是什么原因造成的呢?
解决方案
在聚宽(JoinQuant)平台进行回测或模拟交易时,遇到 订单委托失败 且 error= 后面为空的情况,通常是由底层撮合引擎在订单检查或撮合阶段直接废单引起的。结合您提供的日志信息(时间为 2010-04-01 09:30:00,订单类型为 MarketOrderStyle 市价单),主要有以下几种常见原因:
1. 标的在下单时刻无行情数据(如停牌、未上市或退市)
- 原因分析:您下单的时间是
2010-04-01。如果该股票(600740.XSHG)在这一天处于停牌状态,或者在当时还未上市,系统无法获取到有效的最新价进行撮合,订单会被直接取消,此时 error 提示可能为空。 - 排查建议:在下单前使用
get_current_data()['600740.XSHG'].paused检查该股票当日是否停牌。
2. 市价单 (MarketOrder) 在开盘时刻撮合失败
- 原因分析:日志显示下单时间为
09:30:00,且使用的是市价单(MarketOrderStyle)。在回测中,如果在开盘时刻标的出现一字涨停或开盘无成交量的情况,市价买单会因为无法成交(没有对手盘或超出涨跌停限制)而被系统直接撤销(废单)。 - 排查建议:尝试将市价单改为限价单(
LimitOrderStyle),或者将下单时间稍微延后(例如09:31或09:35),观察是否能够正常成交。
3. 资金不足导致实际可买数量被调整为 0
- 原因分析:您尝试买入的数量为
190260股。聚宽的order函数在执行时,会根据您账户当前的可用资金(available_cash)自动向下调整买入数量。如果您的可用资金不足以买入哪怕 100 股(1手),系统会将下单数量调整为 0,从而导致订单创建失败。 - 排查建议:在下单前打印当前可用资金:
print(context.portfolio.available_cash),并对比当时该股票的股价,确认资金是否充足。
4. 触发了成交量比例限制 (order_volume_ratio)
- 原因分析:聚宽回测默认开启了成交量限制(默认
order_volume_ratio = 0.25,即单笔订单成交量不超过真实市场该分钟/该日成交量的 25%)。如果该股票在 2010-04-01 当天的真实成交量极低,您的下单量(19万股)远超限制,超出部分对于市价单会被直接撤单。
💡 总结与代码优化建议
为了避免此类问题并获得更清晰的错误信息,建议在下单前增加前置条件判断:
def market_open(context):
security = '600740.XSHG'
current_data = get_current_data()
# 1. 检查是否停牌
if current_data[security].paused:
log.info(f"{security} 今日停牌,无法下单")
return
# 2. 检查是否涨停 (防止市价买单废单)
if current_data[security].last_price >= current_data[security].high_limit:
log.info(f"{security} 已涨停,放弃市价买入")
return
# 3. 检查资金是否充足
cash = context.portfolio.available_cash
if cash < current_data[security].last_price * 100:
log.info("可用资金不足以买入1手")
return
# 尝试下单
order(security, 190260)
通过增加这些判断,您可以明确知道订单未成功执行的具体业务原因,避免陷入底层引擎抛出空 error 的困惑。