问题描述
ERROR - 下单失败,初步检查下单数量为0: Order(security=600210.XSHG mode=OrderTargetAmount: _amount=2100 style=MarketOrderStyle: _limit_price=0.0 side=long margin=False entrust_time=None)
2021-05-12 14:58:00 - INFO - Buying 600210.XSHG
2021-05-12 14:58:00 - ERROR - 下单失败,初步检查下单数量为0: Order(security=600210.XSHG mode=OrderTargetAmount: _amount=2100 style=MarketOrderStyle: _limit_price=0.0 side=long margin=False entrust_time=None)
解决方案
在 JoinQuant (聚宽) 平台中使用 order_target 或 order_target_value 函数时,出现 ERROR - 下单失败,初步检查下单数量为0 的提示,通常是因为你期望达到的目标持仓数量(或价值)与当前账户中实际的持仓数量(或价值)已经相等。
因为两者相等,系统计算出需要买入或卖出的实际数量为 0,而交易所是不允许数量为 0 的订单的,因此引擎会拦截该订单并抛出 ERROR 级别的日志提示。
要避免出现这个提示信息,最规范且推荐的做法是在调用下单函数前,增加一个逻辑判断,只有当目标数量与当前持仓数量不一致时,才执行下单操作。
解决方法:增加持仓判断逻辑
你可以通过 context.portfolio.positions 获取当前标的的持仓信息,对比后再下单。代码示例如下:
def handle_data(context, data):
security = '600210.XSHG'
target_amount = 2100 # 你的目标持仓数量
# 获取当前该标的的持仓总数量(如果没有持仓,默认为0)
current_amount = context.portfolio.positions[security].total_amount
# 只有当当前持仓数量不等于目标数量时,才进行下单
if current_amount != target_amount:
log.info(f"Buying {security}, target: {target_amount}, current: {current_amount}")
order_target(security, target_amount)
else:
# 如果已经达到目标数量,可以选择打印 debug 信息或直接 pass
pass
补充说明:关于日志级别的设置
虽然 JoinQuant 提供了 log.set_level('order', 'error') 来过滤日志,但由于“下单数量为0”本身就是一个 ERROR 级别的日志,所以无法通过调高日志级别来简单屏蔽它(除非完全关闭订单日志,但这极不推荐,因为会漏掉真正重要的交易错误)。
因此,养成良好的下单前检查习惯(如上述代码所示)是解决此问题的最佳实践。这不仅能让日志保持干净,还能减少策略运行时的无效计算开销。