StockSharp/StockSharp · error · ArgumentException

Security is not specified.

Error message

Security is not specified.

What it means

The StrategyFitness constructor (inner class of GeneticOptimizer) requires the strategy template to have a Security assigned. The optimizer clones the strategy for each chromosome evaluation, and every clone inherits the Security — if the template's Security is null, all evaluations would fail. The guard surfaces this configuration error at optimizer setup time with an ArgumentException naming the 'strategy' parameter.

Source

Thrown at Algo.Strategies/Optimization/GeneticOptimizer.cs:28

	private class StrategyFitness : IAsyncFitness, IFitness
	{
		private readonly GeneticOptimizer _optimizer;
		private readonly Strategy _strategy;
		private readonly Func<Strategy, decimal> _calcFitness;
		private readonly DateTime _startTime;
		private readonly DateTime _stopTime;
		private readonly SynchronizedDictionary<DynamicTuple, decimal> _cache = [];

		public StrategyFitness(GeneticOptimizer optimizer, Strategy strategy, Func<Strategy, decimal> calcFitness, DateTime startTime, DateTime stopTime)
		{
			_optimizer = optimizer ?? throw new ArgumentNullException(nameof(optimizer));
			_strategy = strategy ?? throw new ArgumentNullException(nameof(strategy));
			_calcFitness = calcFitness ?? throw new ArgumentNullException(nameof(calcFitness));
			_startTime = startTime;
			_stopTime = stopTime;

			if (_strategy.Security is null)
				throw new ArgumentException(LocalizedStrings.SecurityNotSpecified, nameof(strategy));

			if (_strategy.Portfolio is null)
				throw new ArgumentException(LocalizedStrings.PortfolioNotSpecified, nameof(strategy));
		}

		double IFitness.Evaluate(IChromosome chromosome)
			=> throw new NotSupportedException();

		async Task<double> IAsyncFitness.EvaluateAsync(IChromosome chromosome, CancellationToken cancellationToken)
		{
			var spc = (StrategyParametersChromosome)chromosome;

			Strategy strategy;

			using (new Scope<StrategyContext>(new() { ExcludeUI = true }))
				strategy = _strategy.Clone();

			strategy.Security = _strategy.Security;

View on GitHub (pinned to 601a191de6)

Solutions

  1. Set strategy.Security to a valid Security object before passing the strategy to the GeneticOptimizer.
  2. Resolve the SecurityId through the connector's LookupSecurityById before constructing the optimizer.
  3. Validate strategy.Security != null in a pre-optimization check.

Example fix

// before
var optimizer = new GeneticOptimizer(strategyWithoutSecurity, ...);

// after
strategy.Security = connector.LookupSecurityById(securityId);
var optimizer = new GeneticOptimizer(strategy, ...);
Defensive patterns

Strategy: validation

Validate before calling

if (strategy.Security is null)
    throw new InvalidOperationException(
        "Set strategy.Security before creating the GeneticOptimizer.");

var optimizer = new GeneticOptimizer(strategy, ...);

Prevention

When it happens

Trigger: Passing a strategy to the GeneticOptimizer where strategy.Security has not been set. The strategy template was loaded from configuration without resolving the security.

Common situations: Configuring the genetic optimizer from code and forgetting to set Security on the template strategy. Loading a strategy from XML/JSON where the SecurityId was invalid and resolved to null. Using a newly constructed strategy without completing initialization.

Related errors


AI-assisted analysis of StockSharp/StockSharp@601a191de6 (2026-08-13). Data as JSON: /api/errors/e4c533ad887279bb. Report an issue: GitHub.