QuantConnect/Lean · error · ArgumentException

ShareClassMeanReversionAlphaModel: symbols parameter must co

Error message

ShareClassMeanReversionAlphaModel: symbols parameter must contain 2 elements

What it means

ShareClassMeanReversionAlphaModel is a benchmark pairs-trading alpha that builds a mean-reversion signal between two share classes of the same company (e.g. VIA/VIAB). Its constructor is dimensionally fixed at two symbols because the internal logic — alpha/beta regression, an SMA(2) over the dollar-neutral spread, and a RollingWindow(2) — assigns _longSymbol = symbols[0] and _shortSymbol = symbols[1]. Passing any count other than 2 throws ArgumentException at construction, since indexing the array beyond/below a pair would break the strategy.

Source

Thrown at Algorithm.CSharp/Alphas/ShareClassMeanReversionAlpha.cs:94

        private class ShareClassMeanReversionAlphaModel : AlphaModel
        {
            private const double _insightMagnitude = 0.001;
            private readonly Symbol _longSymbol;
            private readonly Symbol _shortSymbol;
            private readonly TimeSpan _insightPeriod;
            private readonly SimpleMovingAverage _sma;
            private readonly RollingWindow<decimal> _positionWindow;
            private decimal _alpha;
            private decimal _beta;
            private bool _invested;

            public ShareClassMeanReversionAlphaModel(
                IEnumerable<Symbol> symbols,
                Resolution resolution = Resolution.Minute)
            {
                if (symbols.Count() != 2)
                {
                    throw new ArgumentException("ShareClassMeanReversionAlphaModel: symbols parameter must contain 2 elements");
                }
                _longSymbol = symbols.ToArray()[0];
                _shortSymbol = symbols.ToArray()[1];
                _insightPeriod = resolution.ToTimeSpan().Multiply(5);
                _sma = new SimpleMovingAverage(2);
                _positionWindow = new RollingWindow<decimal>(2);
            }

            public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
            {
                // Check to see if either ticker will return a NoneBar, and skip the data slice if so
                if (data.Bars.Count < 2)
                {
                    return Enumerable.Empty<Insight>();
                }

                // If Alpha and Beta haven't been calculated yet, then do so
                if (_alpha == 0 || _beta == 0)

View on GitHub (pinned to d2c3659f87)

Solutions

  1. Pass exactly two Symbol objects: the long share class and the short share class (e.g. VIA, VIAB).
  2. If symbols come from a universe, materialize to a list first and assert/branch on the count before constructing the model.
  3. Do not reuse this alpha model for strategies needing a different number of legs — it is hard-coded to a pair.
  4. When copying the model, keep the symbols = new[] { ... }.Select(...).Create(...) pattern so the enumerable is a stable two-element array.

Example fix

// before
var symbols = SelectedSymbols; // count unknown / variable
SetAlpha(new ShareClassMeanReversionAlphaModel(symbols));

// after
var symbols = new[] { "VIA", "VIAB" }
    .Select(x => QuantConnect.Symbol.Create(x, SecurityType.Equity, Market.USA));
SetAlpha(new ShareClassMeanReversionAlphaModel(symbols));
Defensive patterns

Strategy: validation

Validate before calling

// Validate before constructing the alpha model
var symbolList = symbols.ToList();
if (symbolList.Count != 2)
{
    throw new InvalidOperationException(
        $"ShareClassMeanReversionAlphaModel requires exactly 2 symbols, got {symbolList.Count}.");
}
SetAlpha(new ShareClassMeanReversionAlphaModel(symbolList));

Type guard

static bool IsValidPair(IEnumerable<Symbol> symbols)
{
    var list = symbols as ICollection<Symbol> ?? symbols.ToList();
    return list.Count == 2 && list.All(s => s != null);
}

Prevention

When it happens

Trigger: Constructing new ShareClassMeanReversionAlphaModel(symbols) where the IEnumerable<Symbol> resolves to a Count() != 2 — e.g. an empty list, a single ticker, or a universe selection result that yielded 3+ securities. The check symbols.Count() != 2 fires immediately in the ctor before any indicator state is set up.

Common situations: Adapting the benchmark alpha to a custom pair but passing a single symbol; wiring SetAlpha to a live UniverseSelectionModel whose selected set varies in size; refactoring the symbol list and dropping one ticker; reusing this model class for a non-pairs strategy.

Related errors


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