QuantConnect/Lean · error · ArgumentException

Algorithm did not process the option expiration like expecte

Error message

Algorithm did not process the option expiration like expected

What it means

Thrown in OnEndOfAlgorithm when _optionExpired was never set to true. The flag is set inside OnOrderEvent when an order event message contains 'OTM' (out-of-the-money expiration). If no such event fires, the option expiration was not processed by the engine during the algorithm's lifetime.

Source

Thrown at Algorithm.CSharp/BasicTemplateOptionsDailyAlgorithm.cs:108

            // Check for our expected OTM option expiry
            if (orderEvent.Message.Contains("OTM", StringComparison.InvariantCulture))
            {
                // Assert it is at midnight (5AM UTC)
                if (orderEvent.UtcTime != new DateTime(2016, 1, 16, 5, 0, 0))
                {
                    throw new ArgumentException($"Expiry event was not at the correct time, {orderEvent.UtcTime}");
                }

                _optionExpired = true;
            }
        }

        public override void OnEndOfAlgorithm()
        {
            // Assert we had our option expire and fill a liquidation order
            if (_optionExpired != true)
            {
                throw new ArgumentException("Algorithm did not process the option expiration like expected");
            }
        }

        /// <summary>
        /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
        /// </summary>
        public bool CanRunLocally { get; } = true;

        /// <summary>
        /// This is used by the regression test system to indicate which languages this algorithm is written in.
        /// </summary>
        public List<Language> Languages { get; } = new() { Language.CSharp, Language.Python };

        /// <summary>
        /// Data Points count of all timeslices of algorithm
        /// </summary>
        public long DataPoints => 308;

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Verify the selected option contract expires within the backtest window (log contract.Expiry in OnData).
  2. Ensure the algorithm holds the contract to expiration (no premature Liquidate call).
  3. Check OnOrderEvent for all event messages to confirm whether an OTM expiration event fires at all.
  4. Inspect the Lean engine's option-expiration event message format for changes to the 'OTM' string.
  5. Log every orderEvent.Message to trace the full event sequence.

Example fix

// before — no visibility into event sequence
public override void OnOrderEvent(OrderEvent orderEvent)
{
    if (orderEvent.Message.Contains("OTM"))
    {
        _optionExpired = true;
    }
}

// after — log all events for diagnosis
public override void OnOrderEvent(OrderEvent orderEvent)
{
    Log($"OrderEvent: status={orderEvent.Status} msg='{orderEvent.Message}' time={orderEvent.UtcTime}");
    if (orderEvent.Message.Contains("OTM"))
    {
        _optionExpired = true;
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Log all order events to trace expiration processing
public override void OnOrderEvent(OrderEvent orderEvent)
{
    Log($"OrderEvent: status={orderEvent.Status} symbol={orderEvent.Symbol} msg='{orderEvent.Message}' time={orderEvent.UtcTime}");
}

// In OnEndOfAlgorithm, check flag with diagnostics
if (_optionExpired != true)
{
    Log("Option expiration was not processed — review OnOrderEvent log for expiry events");
}

Prevention

When it happens

Trigger: The option contract did not expire within the backtest date range (2015-12-15 to 2016-02-01), the expiration event's message does not contain 'OTM', the contract was not held to expiration, or the engine failed to generate the expiration order event.

Common situations: Option contract selection logic changes (contract picked has a different expiry), message format changes in the expiration event, the contract was liquidated before expiry, or engine-level option-expiry event generation is broken.

Related errors


AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13). Data as JSON: /api/errors/ed6452812b438899. Report an issue: GitHub.