/// <summary> /// Initializes a new instance of the <see cref="StartBacktestCommand"/> class. /// </summary> /// <param name="inputs">inputs.</param> public StartBacktestCommand(string[] inputs) : base(inputs) { Parser parser = new Parser(x => x.HelpWriter = null); parser.ParseArguments <StartBacktestCommandArguments>(inputs) .WithNotParsed(_ => throw new InvalidCommandException("invalid arguments, use help to get more info")) .WithParsed(x => _args = x); // Check if the input type is a valid algorithm _algo = Reflections.GetAllImplementations(typeof(IBaseAlgorithm)) .FirstOrDefault(x => x.Name == _args.AlgorithmName) ?? throw new InvalidCommandException($"{_args.AlgorithmName} is not a known algorithm"); // Retrieve the settings type var settingsType = Reflections.GetAllSubtypes(typeof(AlgorithmConfiguration)) .FirstOrDefault(s => Reflections.AlgorithmMatchesConfiguration(_algo, s)) ?? throw new InvalidCommandException( $"{_args.AlgorithmName} does not have a configuration object and cannot be started."); // Optionally load with custom path. if (!_args.Inline) { _args.ConfigurationPath = _args.ConfigurationPath ?? _args.AlgorithmName + ".yaml"; try { _configuration = ConfigurationLoader.LoadConfiguration(settingsType, _args.ConfigurationPath); } catch (Exception e) { throw new InvalidCommandException(e.Message); } } else { _configuration = BacktestDaemonService.GetConfigurationFromUser(settingsType); } DatabaseUtilities.Instance.ValidateCandleWidth(_configuration.TradingPairs, Configuration.Configuration.Instance.CandleWidth); ConfigureTimestampEdges(BacktestDaemonService.Instance.State, _args); Program.CommandLineArgs.BacktestOutputPath = _args.OutputPath; }