QuantConnect/Lean · error · AssertionError
Expected no options holdings after closing position
Error message
Expected no options holdings after closing position
What it means
In assert_future_option_contract_order, after a BUY fill (closing the short put) the option holdings must be flat (quantity == 0). A non-zero quantity means the close didn't fully flatten the position, leaving residual option exposure.
Source
Thrown at Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py:97
security = self.securities[order_event.symbol]
if security.symbol == self.es19m20:
raise AssertionError(f"Expected no order events for underlying Symbol {security.symbol}")
if security.symbol == self.expected_contract:
self.assert_future_option_contract_order(order_event, security)
else:
raise AssertionError(f"Received order event for unknown Symbol: {order_event.symbol}")
self.log(f"{order_event}")
def assert_future_option_contract_order(self, order_event: OrderEvent, option_contract: Security):
if order_event.direction == OrderDirection.SELL and option_contract.holdings.quantity != -1:
raise AssertionError(f"No holdings were created for option contract {option_contract.symbol}")
if order_event.direction == OrderDirection.BUY and option_contract.holdings.quantity != 0:
raise AssertionError("Expected no options holdings after closing position")
if order_event.is_assignment:
raise AssertionError(f"Assignment was not expected for {order_event.symbol}")
def on_end_of_algorithm(self):
if self.portfolio.invested:
raise AssertionError(f"Expected no holdings at end of algorithm, but are invested in: {', '.join([str(i.id) for i in self.portfolio.keys()])}")
View on GitHub (pinned to d2c3659f87)
Solutions
- Ensure the closing buy order quantity equals the open short quantity (1 contract here).
- Look for intermediate fills that changed the position size before the close.
- Verify no auto-exercise/assignment altered holdings between open and close.
Defensive patterns
Strategy: validation
Validate before calling
# Before the close, verify the open short size and submit a matching close
open_qty = abs(option_contract.holdings.quantity)
if open_qty > 0:
self.market_order(option_contract.symbol, open_qty) # close Prevention
- Always close with a quantity equal to the open position magnitude.
- After closing, assert holdings are flat before the next step rather than only at end-of-algorithm.
When it happens
Trigger: An OrderEvent with direction == OrderDirection.BUY fills but option_contract.holdings.quantity != 0 — e.g., the buy only partially closed a -2 position, or an extra contract was opened.
Common situations: Closing order quantity mismatched the open position, partial fill, or a second contract was opened instead of closing the existing one.
Related errors
- No holdings were created for option contract {option_contrac
- Expected no holdings at end of algorithm, but are invested i
- CustomMarginInterestRateModel was not called
- [{UtcTime}] We hold a delisted securities: {string.Join(",",
- We expected some FOP trading to happen
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/6c777468445207f7.
Report an issue: GitHub.