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
- Pass exactly two Symbol objects: the long share class and the short share class (e.g. VIA, VIAB).
- If symbols come from a universe, materialize to a list first and assert/branch on the count before constructing the model.
- Do not reuse this alpha model for strategies needing a different number of legs — it is hard-coded to a pair.
- 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
- Always pass a fixed two-element array of Symbols to this alpha model.
- When wiring from a universe, materialize and count before constructing.
- Do not reuse this dimensionally-fixed model for non-pair strategies.
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
- The total number of insights should be {expected}. Actual: {
- Indicators are not ready!
- Index is not tradable.
- Bar Count {BarCounter} is not expected count of {ExpectedBar
- Unexpected open interest time: {openInterest.Single().EndTim
AI-assisted analysis of QuantConnect/Lean@d2c3659f87 (2026-08-13).
Data as JSON: /api/errors/d8f05eeaeaa85c0b.
Report an issue: GitHub.