/// <summary> /// Create a new instance of an algorithm from a physical dll path. /// </summary> /// <param name="assemblyPath">The path to the assembly's location</param> /// <param name="algorithmNodePacket">Details of the task required</param> /// <returns>A new instance of IAlgorithm, or throws an exception if there was an error</returns> public IAlgorithm CreateAlgorithmInstance(AlgorithmNodePacket algorithmNodePacket, string assemblyPath) { string error; IAlgorithm algorithm; var algorithmName = Config.Get("algorithm-type-name"); var debugNode = algorithmNodePacket as BacktestNodePacket; var debugging = debugNode != null && debugNode.IsDebugging || Config.GetBool("debugging", false); if (debugging && !BaseSetupHandler.InitializeDebugging(algorithmNodePacket, WorkerThread)) { throw new AlgorithmSetupException("Failed to initialize debugging"); } // don't force load times to be fast here since we're running locally, this allows us to debug // and step through some code that may take us longer than the default 10 seconds var loader = new Loader(debugging, algorithmNodePacket.Language, TimeSpan.FromHours(1), names => names.SingleOrDefault(name => MatchTypeName(name, algorithmName)), WorkerThread); var complete = loader.TryCreateAlgorithmInstanceWithIsolator(assemblyPath, algorithmNodePacket.RamAllocation, out algorithm, out error); if (!complete) { throw new AlgorithmSetupException($"During the algorithm initialization, the following exception has occurred: {error}"); } return(algorithm); }
/// <summary> /// Create a new instance of an algorithm from a physical dll path. /// </summary> /// <param name="assemblyPath">The path to the assembly's location</param> /// <param name="algorithmNodePacket">Details of the task required</param> /// <returns>A new instance of IAlgorithm, or throws an exception if there was an error</returns> public virtual IAlgorithm CreateAlgorithmInstance(AlgorithmNodePacket algorithmNodePacket, string assemblyPath) { string error; IAlgorithm algorithm; var debugNode = algorithmNodePacket as BacktestNodePacket; var debugging = debugNode != null && debugNode.IsDebugging || Config.GetBool("debugging", false); if (debugging && !BaseSetupHandler.InitializeDebugging(algorithmNodePacket, WorkerThread)) { throw new AlgorithmSetupException("Failed to initialize debugging"); } // Limit load times to 90 seconds and force the assembly to have exactly one derived type var loader = new Loader(debugging, algorithmNodePacket.Language, TimeSpan.FromSeconds(90), names => names.SingleOrAlgorithmTypeName(Config.Get("algorithm-type-name")), WorkerThread); var complete = loader.TryCreateAlgorithmInstanceWithIsolator(assemblyPath, algorithmNodePacket.RamAllocation, out algorithm, out error); if (!complete) { throw new AlgorithmSetupException($"During the algorithm initialization, the following exception has occurred: {error}"); } return(algorithm); }
/// <summary> /// Primary entry point to setup a new algorithm /// </summary> /// <param name="parameters">The parameters object to use</param> /// <returns>True on successfully setting up the algorithm state, or false on error.</returns> public bool Setup(SetupHandlerParameters parameters) { var algorithm = parameters.Algorithm; var brokerage = parameters.Brokerage; // verify we were given the correct job packet type var liveJob = parameters.AlgorithmNodePacket as LiveNodePacket; if (liveJob == null) { AddInitializationError("BrokerageSetupHandler requires a LiveNodePacket"); return(false); } algorithm.Name = liveJob.GetAlgorithmName(); // verify the brokerage was specified if (string.IsNullOrWhiteSpace(liveJob.Brokerage)) { AddInitializationError("A brokerage must be specified"); return(false); } // attach to the message event to relay brokerage specific initialization messages EventHandler <BrokerageMessageEvent> brokerageOnMessage = (sender, args) => { if (args.Type == BrokerageMessageType.Error) { AddInitializationError($"Brokerage Error Code: {args.Code} - {args.Message}"); } }; try { Log.Trace("BrokerageSetupHandler.Setup(): Initializing algorithm..."); parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.Initializing, "Initializing algorithm..."); //Execute the initialize code: var controls = liveJob.Controls; var isolator = new Isolator(); var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(300), () => { try { //Set the default brokerage model before initialize algorithm.SetBrokerageModel(_factory.BrokerageModel); //Margin calls are disabled by default in live mode algorithm.Portfolio.MarginCallModel = MarginCallModel.Null; //Set our parameters algorithm.SetParameters(liveJob.Parameters); algorithm.SetAvailableDataTypes(GetConfiguredDataFeeds()); //Algorithm is live, not backtesting: algorithm.SetLiveMode(true); //Initialize the algorithm's starting date algorithm.SetDateTime(DateTime.UtcNow); //Set the source impl for the event scheduling algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler); // set the option chain provider algorithm.SetOptionChainProvider(new CachingOptionChainProvider(new LiveOptionChainProvider())); // set the future chain provider algorithm.SetFutureChainProvider(new CachingFutureChainProvider(new LiveFutureChainProvider())); // If we're going to receive market data from IB, // set the default subscription limit to 100, // algorithms can override this setting in the Initialize method if (brokerage is InteractiveBrokersBrokerage && liveJob.DataQueueHandler.EndsWith("InteractiveBrokersBrokerage")) { algorithm.Settings.DataSubscriptionLimit = 100; } //Initialise the algorithm, get the required data: algorithm.Initialize(); if (algorithm.AccountCurrency != Currencies.USD) { throw new NotImplementedException( "BrokerageSetupHandler.Setup(): calling 'QCAlgorithm.SetAccountCurrency()' " + "is only supported in backtesting for now."); } if (liveJob.Brokerage != "PaperBrokerage") { //Zero the CashBook - we'll populate directly from brokerage foreach (var kvp in algorithm.Portfolio.CashBook) { kvp.Value.SetAmount(0); } } } catch (Exception err) { AddInitializationError(err.ToString(), err); } }, controls.RamAllocation, sleepIntervalMillis: 50); // entire system is waiting on this, so be as fast as possible if (!initializeComplete) { AddInitializationError("Initialization timed out."); return(false); } // let the world know what we're doing since logging in can take a minute parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.LoggingIn, "Logging into brokerage..."); brokerage.Message += brokerageOnMessage; Log.Trace("BrokerageSetupHandler.Setup(): Connecting to brokerage..."); try { // this can fail for various reasons, such as already being logged in somewhere else brokerage.Connect(); } catch (Exception err) { Log.Error(err); AddInitializationError( $"Error connecting to brokerage: {err.Message}. " + "This may be caused by incorrect login credentials or an unsupported account type.", err); return(false); } if (!brokerage.IsConnected) { // if we're reporting that we're not connected, bail AddInitializationError("Unable to connect to brokerage."); return(false); } Log.Trace("BrokerageSetupHandler.Setup(): Fetching cash balance from brokerage..."); try { // set the algorithm's cash balance for each currency var cashBalance = brokerage.GetCashBalance(); foreach (var cash in cashBalance) { Log.Trace("BrokerageSetupHandler.Setup(): Setting " + cash.Currency + " cash to " + cash.Amount); algorithm.Portfolio.SetCash(cash.Currency, cash.Amount, 0); } } catch (Exception err) { Log.Error(err); AddInitializationError("Error getting cash balance from brokerage: " + err.Message, err); return(false); } var supportedSecurityTypes = new HashSet <SecurityType> { SecurityType.Equity, SecurityType.Forex, SecurityType.Cfd, SecurityType.Option, SecurityType.Future, SecurityType.Crypto }; var minResolution = new Lazy <Resolution>(() => algorithm.Securities.Select(x => x.Value.Resolution).DefaultIfEmpty(Resolution.Second).Min()); Log.Trace("BrokerageSetupHandler.Setup(): Fetching open orders from brokerage..."); try { GetOpenOrders(algorithm, parameters.ResultHandler, parameters.TransactionHandler, brokerage, supportedSecurityTypes, minResolution.Value); } catch (Exception err) { Log.Error(err); AddInitializationError("Error getting open orders from brokerage: " + err.Message, err); return(false); } Log.Trace("BrokerageSetupHandler.Setup(): Fetching holdings from brokerage..."); try { // populate the algorithm with the account's current holdings var holdings = brokerage.GetAccountHoldings(); // add options first to ensure raw data normalization mode is set on the equity underlyings foreach (var holding in holdings.OrderByDescending(x => x.Type)) { Log.Trace("BrokerageSetupHandler.Setup(): Has existing holding: " + holding); // verify existing holding security type if (!supportedSecurityTypes.Contains(holding.Type)) { Log.Error("BrokerageSetupHandler.Setup(): Unsupported security type: " + holding.Type + "-" + holding.Symbol.Value); AddInitializationError("Found unsupported security type in existing brokerage holdings: " + holding.Type + ". " + "QuantConnect currently supports the following security types: " + string.Join(",", supportedSecurityTypes)); // keep aggregating these errors continue; } AddUnrequestedSecurity(algorithm, holding.Symbol, minResolution.Value); algorithm.Portfolio[holding.Symbol].SetHoldings(holding.AveragePrice, holding.Quantity); algorithm.Securities[holding.Symbol].SetMarketPrice(new TradeBar { Time = DateTime.Now, Open = holding.MarketPrice, High = holding.MarketPrice, Low = holding.MarketPrice, Close = holding.MarketPrice, Volume = 0, Symbol = holding.Symbol, DataType = MarketDataType.TradeBar }); } } catch (Exception err) { Log.Error(err); AddInitializationError("Error getting account holdings from brokerage: " + err.Message, err); return(false); } //Finalize Initialization algorithm.PostInitialize(); BaseSetupHandler.SetupCurrencyConversions(algorithm, parameters.UniverseSelection); //Set the starting portfolio value for the strategy to calculate performance: StartingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue; StartingDate = DateTime.Now; } catch (Exception err) { AddInitializationError(err.ToString(), err); } finally { if (brokerage != null) { brokerage.Message -= brokerageOnMessage; } } return(Errors.Count == 0); }
/// <summary> /// Setup the algorithm cash, dates and data subscriptions as desired. /// </summary> /// <param name="parameters">The parameters object to use</param> /// <returns>Boolean true on successfully initializing the algorithm</returns> public bool Setup(SetupHandlerParameters parameters) { var algorithm = parameters.Algorithm; var job = parameters.AlgorithmNodePacket as BacktestNodePacket; if (job == null) { throw new ArgumentException("Expected BacktestNodePacket but received " + parameters.AlgorithmNodePacket.GetType().Name); } Log.Trace(string.Format("BacktestingSetupHandler.Setup(): Setting up job: Plan: {0}, UID: {1}, PID: {2}, Version: {3}, Source: {4}", job.UserPlan, job.UserId, job.ProjectId, job.Version, job.RequestSource)); if (algorithm == null) { Errors.Add(new AlgorithmSetupException("Could not create instance of algorithm")); return(false); } algorithm.Name = job.GetAlgorithmName(); //Make sure the algorithm start date ok. if (job.PeriodStart == default(DateTime)) { Errors.Add(new AlgorithmSetupException("Algorithm start date was never set")); return(false); } var controls = job.Controls; var isolator = new Isolator(); var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromMinutes(5), () => { try { parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.Initializing, "Initializing algorithm..."); //Set our parameters algorithm.SetParameters(job.Parameters); //Algorithm is backtesting, not live: algorithm.SetLiveMode(false); //Set the source impl for the event scheduling algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler); // set the option chain provider algorithm.SetOptionChainProvider(new CachingOptionChainProvider(new BacktestingOptionChainProvider())); // set the future chain provider algorithm.SetFutureChainProvider(new CachingFutureChainProvider(new BacktestingFutureChainProvider())); //Initialise the algorithm, get the required data: algorithm.Initialize(); // finalize initialization algorithm.PostInitialize(); } catch (Exception err) { Log.Error(err); Errors.Add(new AlgorithmSetupException("During the algorithm initialization, the following exception has occurred: ", err)); } }, controls.RamAllocation, sleepIntervalMillis: 50); // entire system is waiting on this, so be as fast as possible //Before continuing, detect if this is ready: if (!initializeComplete) { return(false); } // TODO: Refactor the BacktestResultHandler to use algorithm not job to set times job.PeriodStart = algorithm.StartDate; job.PeriodFinish = algorithm.EndDate; //Calculate the max runtime for the strategy _maxRuntime = GetMaximumRuntime(job.PeriodStart, job.PeriodFinish, algorithm.SubscriptionManager, algorithm.UniverseManager, parameters.AlgorithmNodePacket.Controls); // Python takes forever; lets give it 10x longer to finish. if (job.Language == Language.Python) { _maxRuntime = _maxRuntime.Add(TimeSpan.FromSeconds(_maxRuntime.TotalSeconds * 9)); } BaseSetupHandler.SetupCurrencyConversions(algorithm, parameters.UniverseSelection); StartingPortfolioValue = algorithm.Portfolio.Cash; //Max Orders: 10k per backtest: if (job.UserPlan == UserPlan.Free) { _maxOrders = 10000; } else { _maxOrders = int.MaxValue; _maxRuntime += _maxRuntime; } //Set back to the algorithm, algorithm.SetMaximumOrders(_maxOrders); //Starting date of the algorithm: _startingDate = job.PeriodStart; //Put into log for debugging: Log.Trace("SetUp Backtesting: User: "******" ProjectId: " + job.ProjectId + " AlgoId: " + job.AlgorithmId); Log.Trace("Dates: Start: " + job.PeriodStart.ToShortDateString() + " End: " + job.PeriodFinish.ToShortDateString() + " Cash: " + StartingPortfolioValue.ToString("C")); if (Errors.Count > 0) { initializeComplete = false; } return(initializeComplete); }
/// <summary> /// Primary entry point to setup a new algorithm /// </summary> /// <param name="parameters">The parameters object to use</param> /// <returns>True on successfully setting up the algorithm state, or false on error.</returns> public bool Setup(SetupHandlerParameters parameters) { var algorithm = parameters.Algorithm; var brokerage = parameters.Brokerage; // verify we were given the correct job packet type var liveJob = parameters.AlgorithmNodePacket as LiveNodePacket; if (liveJob == null) { AddInitializationError("BrokerageSetupHandler requires a LiveNodePacket"); return(false); } algorithm.Name = liveJob.GetAlgorithmName(); // verify the brokerage was specified if (string.IsNullOrWhiteSpace(liveJob.Brokerage)) { AddInitializationError("A brokerage must be specified"); return(false); } // attach to the message event to relay brokerage specific initialization messages EventHandler <BrokerageMessageEvent> brokerageOnMessage = (sender, args) => { if (args.Type == BrokerageMessageType.Error) { AddInitializationError($"Brokerage Error Code: {args.Code} - {args.Message}"); } }; try { // let the world know what we're doing since logging in can take a minute parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.LoggingIn, "Logging into brokerage..."); brokerage.Message += brokerageOnMessage; Log.Trace("BrokerageSetupHandler.Setup(): Connecting to brokerage..."); try { // this can fail for various reasons, such as already being logged in somewhere else brokerage.Connect(); } catch (Exception err) { Log.Error(err); AddInitializationError( $"Error connecting to brokerage: {err.Message}. " + "This may be caused by incorrect login credentials or an unsupported account type.", err); return(false); } if (!brokerage.IsConnected) { // if we're reporting that we're not connected, bail AddInitializationError("Unable to connect to brokerage."); return(false); } var message = $"{brokerage.Name} account base currency: {brokerage.AccountBaseCurrency ?? algorithm.AccountCurrency}"; var accountCurrency = brokerage.AccountBaseCurrency; if (liveJob.BrokerageData.ContainsKey(MaxAllocationLimitConfig)) { accountCurrency = Currencies.USD; message += ". Allocation limited, will use 'USD' account currency"; } Log.Trace($"BrokerageSetupHandler.Setup(): {message}"); algorithm.Debug(message); if (accountCurrency != null && accountCurrency != algorithm.AccountCurrency) { algorithm.SetAccountCurrency(accountCurrency); } Log.Trace("BrokerageSetupHandler.Setup(): Initializing algorithm..."); parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.Initializing, "Initializing algorithm..."); //Execute the initialize code: var controls = liveJob.Controls; var isolator = new Isolator(); var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(300), () => { try { //Set the default brokerage model before initialize algorithm.SetBrokerageModel(_factory.GetBrokerageModel(algorithm.Transactions)); //Margin calls are disabled by default in live mode algorithm.Portfolio.MarginCallModel = MarginCallModel.Null; //Set our parameters algorithm.SetParameters(liveJob.Parameters); algorithm.SetAvailableDataTypes(BaseSetupHandler.GetConfiguredDataFeeds()); //Algorithm is live, not backtesting: algorithm.SetLiveMode(true); //Initialize the algorithm's starting date algorithm.SetDateTime(DateTime.UtcNow); //Set the source impl for the event scheduling algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler); var optionChainProvider = Composer.Instance.GetPart <IOptionChainProvider>(); if (optionChainProvider == null) { optionChainProvider = new CachingOptionChainProvider(new LiveOptionChainProvider()); } // set the option chain provider algorithm.SetOptionChainProvider(optionChainProvider); var futureChainProvider = Composer.Instance.GetPart <IFutureChainProvider>(); if (futureChainProvider == null) { futureChainProvider = new CachingFutureChainProvider(new LiveFutureChainProvider()); } // set the future chain provider algorithm.SetFutureChainProvider(futureChainProvider); // set the object store algorithm.SetObjectStore(parameters.ObjectStore); // If we're going to receive market data from IB, // set the default subscription limit to 100, // algorithms can override this setting in the Initialize method if (brokerage is InteractiveBrokersBrokerage && liveJob.DataQueueHandler.EndsWith("InteractiveBrokersBrokerage")) { algorithm.Settings.DataSubscriptionLimit = 100; } //Initialise the algorithm, get the required data: algorithm.Initialize(); if (liveJob.Brokerage != "PaperBrokerage") { //Zero the CashBook - we'll populate directly from brokerage foreach (var kvp in algorithm.Portfolio.CashBook) { kvp.Value.SetAmount(0); } } } catch (Exception err) { AddInitializationError(err.ToString(), err); } }, controls.RamAllocation, sleepIntervalMillis: 100); // entire system is waiting on this, so be as fast as possible if (Errors.Count != 0) { // if we already got an error just exit right away return(false); } if (!initializeComplete) { AddInitializationError("Initialization timed out."); return(false); } if (!LoadCashBalance(brokerage, algorithm)) { return(false); } if (!LoadExistingHoldingsAndOrders(brokerage, algorithm, parameters)) { return(false); } //Finalize Initialization algorithm.PostInitialize(); BaseSetupHandler.SetupCurrencyConversions(algorithm, parameters.UniverseSelection); if (algorithm.Portfolio.TotalPortfolioValue == 0) { algorithm.Debug("Warning: No cash balances or holdings were found in the brokerage account."); } string maxCashLimitStr; if (liveJob.BrokerageData.TryGetValue(MaxAllocationLimitConfig, out maxCashLimitStr)) { var maxCashLimit = decimal.Parse(maxCashLimitStr, NumberStyles.Any, CultureInfo.InvariantCulture); // If allocation exceeded by more than $10,000; block deployment if (algorithm.Portfolio.TotalPortfolioValue > (maxCashLimit + 10000m)) { var exceptionMessage = $"TotalPortfolioValue '{algorithm.Portfolio.TotalPortfolioValue}' exceeds allocation limit '{maxCashLimit}'"; algorithm.Debug(exceptionMessage); throw new ArgumentException(exceptionMessage); } } //Set the starting portfolio value for the strategy to calculate performance: StartingPortfolioValue = algorithm.Portfolio.TotalPortfolioValue; StartingDate = DateTime.Now; // we set the free portfolio value based on the initial total value and the free percentage value algorithm.Settings.FreePortfolioValue = algorithm.Portfolio.TotalPortfolioValue * algorithm.Settings.FreePortfolioValuePercentage; } catch (Exception err) { AddInitializationError(err.ToString(), err); } finally { if (brokerage != null) { brokerage.Message -= brokerageOnMessage; } } return(Errors.Count == 0); }
/// <summary> /// Setup the algorithm cash, dates and data subscriptions as desired. /// </summary> /// <param name="parameters">The parameters object to use</param> /// <returns>Boolean true on successfully initializing the algorithm</returns> public bool Setup(SetupHandlerParameters parameters) { var algorithm = parameters.Algorithm; var job = parameters.AlgorithmNodePacket as BacktestNodePacket; if (job == null) { throw new ArgumentException("Expected BacktestNodePacket but received " + parameters.AlgorithmNodePacket.GetType().Name); } Log.Trace($"BacktestingSetupHandler.Setup(): Setting up job: Plan: {job.UserPlan}, UID: {job.UserId.ToStringInvariant()}, " + $"PID: {job.ProjectId.ToStringInvariant()}, Version: {job.Version}, Source: {job.RequestSource}" ); if (algorithm == null) { Errors.Add(new AlgorithmSetupException("Could not create instance of algorithm")); return(false); } algorithm.Name = job.GetAlgorithmName(); //Make sure the algorithm start date ok. if (job.PeriodStart == default(DateTime)) { Errors.Add(new AlgorithmSetupException("Algorithm start date was never set")); return(false); } var controls = job.Controls; var isolator = new Isolator(); var initializeComplete = isolator.ExecuteWithTimeLimit(TimeSpan.FromMinutes(5), () => { try { parameters.ResultHandler.SendStatusUpdate(AlgorithmStatus.Initializing, "Initializing algorithm..."); //Set our parameters algorithm.SetParameters(job.Parameters); //Algorithm is backtesting, not live: algorithm.SetLiveMode(false); //Set the source impl for the event scheduling algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler); // set the option chain provider algorithm.SetOptionChainProvider(new CachingOptionChainProvider(new BacktestingOptionChainProvider())); // set the future chain provider algorithm.SetFutureChainProvider(new CachingFutureChainProvider(new BacktestingFutureChainProvider())); // set the object store algorithm.SetObjectStore(parameters.ObjectStore); // before we call initialize BaseSetupHandler.LoadBacktestJobAccountCurrency(algorithm, job); //Initialise the algorithm, get the required data: algorithm.Initialize(); // set start and end date if present in the job if (job.PeriodStart.HasValue) { algorithm.SetStartDate(job.PeriodStart.Value); } if (job.PeriodFinish.HasValue) { algorithm.SetEndDate(job.PeriodFinish.Value); } // after we call initialize BaseSetupHandler.LoadBacktestJobCashAmount(algorithm, job); // finalize initialization algorithm.PostInitialize(); } catch (Exception err) { Log.Error(err); Errors.Add(new AlgorithmSetupException("During the algorithm initialization, the following exception has occurred: ", err)); } }, controls.RamAllocation, sleepIntervalMillis: 10, // entire system is waiting on this, so be as fast as possible workerThread: WorkerThread); //Before continuing, detect if this is ready: if (!initializeComplete) { return(false); } //Calculate the max runtime for the strategy MaximumRuntime = GetMaximumRuntime(algorithm.StartDate, algorithm.EndDate, algorithm.SubscriptionManager, algorithm.UniverseManager, parameters.AlgorithmNodePacket.Controls); // Python takes forever; lets give it 10x longer to finish. if (job.Language == Language.Python) { MaximumRuntime = MaximumRuntime.Add(TimeSpan.FromSeconds(MaximumRuntime.TotalSeconds * 9)); } BaseSetupHandler.SetupCurrencyConversions(algorithm, parameters.UniverseSelection); StartingPortfolioValue = algorithm.Portfolio.Cash; // we set the free portfolio value based on the initial total value and the free percentage value algorithm.Settings.FreePortfolioValue = algorithm.Portfolio.TotalPortfolioValue * algorithm.Settings.FreePortfolioValuePercentage; //Max Orders: 10k per backtest: if (job.UserPlan == UserPlan.Free) { MaxOrders = 10000; } else { MaxOrders = int.MaxValue; MaximumRuntime += MaximumRuntime; } MaxOrders = job.Controls.BacktestingMaxOrders; //Set back to the algorithm, algorithm.SetMaximumOrders(MaxOrders); //Starting date of the algorithm: StartingDate = algorithm.StartDate; //Put into log for debugging: Log.Trace("SetUp Backtesting: User: "******" ProjectId: " + job.ProjectId + " AlgoId: " + job.AlgorithmId); Log.Trace($"Dates: Start: {algorithm.StartDate.ToStringInvariant("d")} " + $"End: {algorithm.EndDate.ToStringInvariant("d")} " + $"Cash: {StartingPortfolioValue.ToStringInvariant("C")}"); if (Errors.Count > 0) { initializeComplete = false; } return(initializeComplete); }
/// <summary> /// Setup the algorithm cash, dates and portfolio as desired. /// </summary> /// <param name="parameters">The parameters object to use</param> /// <returns>Boolean true on successfully setting up the console.</returns> public bool Setup(SetupHandlerParameters parameters) { var algorithm = parameters.Algorithm; var baseJob = parameters.AlgorithmNodePacket; var initializeComplete = false; try { //Set common variables for console programs: if (baseJob.Type == PacketType.BacktestNode) { var backtestJob = baseJob as BacktestNodePacket; if (backtestJob == null) { throw new ArgumentException("Expected BacktestNodePacket but received " + baseJob.GetType().Name); } algorithm.SetMaximumOrders(int.MaxValue); // set our parameters algorithm.SetParameters(baseJob.Parameters); algorithm.SetLiveMode(false); algorithm.SetAvailableDataTypes(GetConfiguredDataFeeds()); //Set the source impl for the event scheduling algorithm.Schedule.SetEventSchedule(parameters.RealTimeHandler); // set the option chain provider algorithm.SetOptionChainProvider(new CachingOptionChainProvider(new BacktestingOptionChainProvider())); // set the future chain provider algorithm.SetFutureChainProvider(new CachingFutureChainProvider(new BacktestingFutureChainProvider())); var isolator = new Isolator(); isolator.ExecuteWithTimeLimit(TimeSpan.FromMinutes(5), () => { //Setup Base Algorithm: algorithm.Initialize(); }, baseJob.Controls.RamAllocation, sleepIntervalMillis: 50, workerThread: WorkerThread); //Finalize Initialization algorithm.PostInitialize(); //Set the time frontier of the algorithm algorithm.SetDateTime(algorithm.StartDate.ConvertToUtc(algorithm.TimeZone)); //Construct the backtest job packet: backtestJob.PeriodStart = algorithm.StartDate; backtestJob.PeriodFinish = algorithm.EndDate; //Backtest Specific Parameters: StartingDate = backtestJob.PeriodStart; BaseSetupHandler.SetupCurrencyConversions(algorithm, parameters.UniverseSelection); StartingPortfolioValue = algorithm.Portfolio.Cash; } else { throw new Exception("The ConsoleSetupHandler is for backtests only. Use the BrokerageSetupHandler."); } } catch (Exception err) { Log.Error(err); Errors.Add(new AlgorithmSetupException("During the algorithm initialization, the following exception has occurred: ", err)); } if (Errors.Count == 0) { initializeComplete = true; } return(initializeComplete); }