/// <summary> /// Calculate the maximum runtime for this algorithm job. /// </summary> /// <param name="start">State date of the algorithm</param> /// <param name="finish">End date of the algorithm</param> /// <param name="subscriptionManager">Subscription Manager</param> /// <param name="universeManager">Universe manager containing configured universes</param> /// <param name="controls">Job controls instance</param> /// <returns>Timespan maximum run period</returns> private TimeSpan GetMaximumRuntime(DateTime start, DateTime finish, SubscriptionManager subscriptionManager, UniverseManager universeManager, Controls controls) { // option/futures chain subscriptions var derivativeSubscriptions = subscriptionManager.Subscriptions .Where(x => x.Symbol.IsCanonical()) .Select(x => controls.GetLimit(x.Resolution)) .Sum(); // universe coarse/fine/custom subscriptions var universeSubscriptions = universeManager // use max limit for universes without explicitly added securities .Sum(u => u.Value.Members.Count == 0 ? controls.GetLimit(u.Value.UniverseSettings.Resolution) : u.Value.Members.Count); var subscriptionCount = derivativeSubscriptions + universeSubscriptions; double maxRunTime = 0; var jobDays = (finish - start).TotalDays; maxRunTime = 10 * subscriptionCount * jobDays; //Rationalize: if ((maxRunTime / 3600) > 12) { //12 hours maximum maxRunTime = 3600 * 12; } else if (maxRunTime < 60) { //If less than 60 seconds. maxRunTime = 60; } Log.Trace("BacktestingSetupHandler.GetMaxRunTime(): Job Days: " + jobDays + " Max Runtime: " + Math.Round(maxRunTime / 60) + " min"); //Override for windows: if (OS.IsWindows) { maxRunTime = 24 * 60 * 60; } return(TimeSpan.FromSeconds(maxRunTime)); }