3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 JoinQuant 聚宽平台中,order_target 等下单函数返回 None 通常是因为订单创建失败(例如:股票停牌、代码错误、退市等)。
而跌停导致市价卖单取消,发生在订单撮合阶段。此时订单已经成功创建,因此 order_target 会返回一个 Order 对象,只是该订单在随后的撮合中因为跌停没有对手盘(市价单机制)而被系统撤销,状态变为了 canceled(已撤销)。
要获取这些被取消的股票代码,您可以通过以下两种方法:
在回测模式下,市价单是同步撮合的。这意味着 order_target 执行完毕后,返回的 Order 对象已经包含了撮合结果。您可以直接检查该对象的 status 属性。
def handle_data(context, data):
security = '300526.XSHE'
# 假设我们要清仓
if context.portfolio.positions[security].closeable_amount > 0:
# 下单并获取返回的 Order 对象
my_order = order_target(security, 0)
# 检查订单是否创建成功且状态为已撤销
if my_order is not None:
# OrderStatus.canceled 的值为 2,也可以转为字符串判断
if str(my_order.status) == 'canceled' and my_order.filled == 0:
log.info(f"股票 {my_order.security} 因跌停或其他原因市价卖单被取消!")
# 在这里记录被取消的股票代码
# canceled_stocks.append(my_order.security)
get_orders() 批量查询如果您想在每天收盘后或特定时间点,统一获取当天所有被取消的卖单,可以使用 get_orders() 函数。
def after_trading_end(context):
# 获取当天所有订单
all_orders = get_orders()
canceled_sell_stocks = []
for order_id, order_obj in all_orders.items():
# 筛选条件:
# 1. 状态为已撤销 (canceled)
# 2. 是卖单 (is_buy == False)
# 3. 成交量为 0 (完全没卖出去)
if str(order_obj.status) == 'canceled' and not order_obj.is_buy and order_obj.filled == 0:
canceled_sell_stocks.append(order_obj.security)
if canceled_sell_stocks:
log.info(f"今日被取消的卖单股票有:{canceled_sell_stocks}")
根据 JoinQuant 的撮合规则:跌停时市价卖单会被撤销,但限价单会挂单等待撮合。
如果您希望在跌停板上排队卖出(这在真实交易中是常见的做法),建议在判断股票可能跌停或已经跌停时,改用跌停价下限价单,而不是市价单。
current_data = get_current_data()
low_limit = current_data[security].low_limit # 获取跌停价
# 使用跌停价下限价单,这样订单会保持 open 状态挂单,而不是被直接 canceled
order_target(security, 0, style=LimitOrderStyle(low_limit))