QuantConnect/Lean · error · AssertionError
OrderEvent StopPrice is Not expected to be 0 for StopMarketO
Error message
OrderEvent StopPrice is Not expected to be 0 for StopMarketOrder
What it means
Self-test assertion in OrderTicketDemoAlgorithm.on_order_event verifying that an OrderEvent for a StopMarketOrder carries a non-zero StopPrice. OrderEvent.StopPrice is a nullable decimal (decimal?) that the engine is expected to populate from the stop order's trigger price. The check `order_event.stop_price == 0` triggers when the field reads as exactly numeric zero for a stop-market order.
Source
Thrown at Algorithm.Python/OrderTicketDemoAlgorithm.py:402
ticket.update(update_order_fields)
def on_order_event(self, order_event):
order = self.transactions.get_order_by_id(order_event.order_id)
self.log("{0}: {1}: {2}".format(self.time, order.type, order_event))
if order_event.quantity == 0:
raise AssertionError("OrderEvent quantity is Not expected to be 0, it should hold the current order Quantity")
if order_event.quantity != order.quantity:
raise AssertionError("OrderEvent quantity should hold the current order Quantity")
if (type(order) is LimitOrder and order_event.limit_price == 0 or
type(order) is StopLimitOrder and order_event.limit_price == 0):
raise AssertionError("OrderEvent LimitPrice is Not expected to be 0 for LimitOrder and StopLimitOrder")
if type(order) is StopMarketOrder and order_event.stop_price == 0:
raise AssertionError("OrderEvent StopPrice is Not expected to be 0 for StopMarketOrder")
# We can access the order ticket from the order event
if order_event.ticket is None:
raise AssertionError("OrderEvent Ticket was not set")
if order_event.order_id != order_event.ticket.order_id:
raise AssertionError("OrderEvent.ORDER_ID and order_event.ticket.order_id do not match")
def check_pair_orders_for_fills(self, long_order, short_order):
if long_order.status == OrderStatus.FILLED:
self.log("{0}: Cancelling short order, long order is filled.".format(short_order.order_type))
short_order.cancel("Long filled.")
return True
if short_order.status == OrderStatus.FILLED:
self.log("{0}: Cancelling long order, short order is filled.".format(long_order.order_type))
long_order.cancel("Short filled")
return True
View on GitHub (pinned to d2c3659f87)
Solutions
- As an engine regression: locate where StopMarketOrder events are constructed and ensure order_event.StopPrice is set from order.StopPrice.
- In your own algorithm: replace the `== 0` check with a nullable-aware comparison against order.stop_price.
- For custom fill/brokerage models: explicitly set order_event.StopPrice = order.StopPrice before the event is dispatched.
- For deserialized events: confirm the source packet includes StopPrice; otherwise re-derive it from the live order.
Example fix
# before
if type(order) is StopMarketOrder and order_event.stop_price == 0:
raise AssertionError("OrderEvent StopPrice is Not expected to be 0 for StopMarketOrder")
# after
if type(order) is StopMarketOrder:
if order_event.stop_price in (None, 0) or order_event.stop_price != order.stop_price:
raise AssertionError(
f"OrderEvent StopPrice mismatch for StopMarketOrder: "
f"event={order_event.stop_price}, order={order.stop_price}") Defensive patterns
Strategy: validation
Validate before calling
order = self.transactions.get_order_by_id(order_event.order_id)
if type(order) is StopMarketOrder:
if order_event.stop_price in (None, 0):
self.debug(f"Skipping event: stop_price unset for StopMarketOrder {order_event.order_id}")
return
# safe to use order_event.stop_price Type guard
def has_valid_stop_price(order, order_event):
"""True only for stop orders whose event stop price is present and non-zero."""
if type(order) is not StopMarketOrder:
return True
sp = order_event.stop_price
return sp is not None and sp != 0 Prevention
- Treat OrderEvent.StopPrice as nullable; check is None, not just == 0.
- When writing a custom stop-order fill model, set order_event.StopPrice from order.StopPrice.
- Prefer comparing the event price to the originating order's price over asserting a specific value.
When it happens
Trigger: An OrderEvent for a StopMarketOrder arrives with order_event.stop_price == 0. This means the earlier quantity checks passed, but the stop price was not propagated from the order to the event. It occurs when a fill model, transaction handler, or deserialization path (e.g. OrderEvent.FromSerialized) builds the event without copying order.StopPrice into StopPrice.
Common situations: Lean contributors hit this in the regression suite after edits to stop-order handling, the fill pipeline, or OrderEvent serialization. Users hit it when a custom stop-order type or brokerage integration emits events without setting StopPrice, or after upgrading Lean if the stop-price propagation contract changed.
Related errors
- OrderEvent LimitPrice is Not expected to be 0 for LimitOrder
- OrderEvent Ticket was not set
- OrderEvent.ORDER_ID and order_event.ticket.order_id do not m
- Order was not canceled
- There should be no open orders
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/2eb51d537fa15a63.
Report an issue: GitHub.