QuantConnect/Lean · error · RegressionTestException

Portfolio should have the stock

Error message

Portfolio should have the stock

What it means

Asserts the final portfolio contains exactly one position group with exactly one position whose symbol is _stock. It uses Positions.Groups.Single().Single(). This enforces that the only thing left in the portfolio is the assigned stock. A failure means either there is more than one group/position, or the single position is not the stock symbol.

Source

Thrown at Algorithm.CSharp/DuplicateOptionAssignmentRegressionAlgorithm.cs:199

            {
                throw new RegressionTestException("Order was not canceled");
            }

            var openOrders = Transactions.GetOpenOrders();
            if (openOrders.Count != 0)
            {
                throw new RegressionTestException("There should be no open orders");
            }

            if (!Portfolio.Invested)
            {
                throw new RegressionTestException("Portfolio should be invested");
            }

            // We should have the stock since the option was assigned
            if (Portfolio.Positions.Groups.Single().Single().Symbol != _stock)
            {
                throw new RegressionTestException("Portfolio should have the stock");
            }
        }

        /// <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 };

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

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Enumerate Portfolio.Positions and each group's positions to see what remains besides the stock.
  2. Confirm the option position was removed when the option delisted.
  3. Check that _stock SID equality holds against the delivered position symbol.

Example fix

// before
if (Portfolio.Positions.Groups.Single().Single().Symbol != _stock)
{
    throw new RegressionTestException("Portfolio should have the stock");
}

// after (enumerate to avoid Single() masking the real state)
var positions = Portfolio.Positions.Groups.SelectMany(g => g).ToList();
if (positions.Count != 1 || positions[0].Symbol != _stock)
{
    throw new RegressionTestException(
        $"Portfolio should have only the stock. Got: {string.Join(", ", positions.Select(p => p.Symbol))}");
}
Defensive patterns

Strategy: validation

Validate before calling

var positions = Portfolio.Positions.Select(p => (p.Symbol, p.Quantity)).ToList();
if (positions.Count != 1 || positions[0].Symbol != _stock)
{
    foreach (var p in positions) Log($"Position: {p.Symbol} qty={p.Quantity}");
}

Prevention

When it happens

Trigger: Multiple position groups remain (option + stock), or the lone position is a different symbol. The delisting did not remove the option from the portfolio.

Common situations: The option position was not removed after delisting (extra position remains); the stock symbol SID does not match _stock; a duplicate security lingers; .Single() throws InvalidOperationException (which surfaces differently) when there are zero or multiple.

Related errors


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