public override List<OptimizationResult> RunOptimization(SystemRunSettings runSettings)
		{
			SetupOptimization();

			List<OptimizationResult> ret = new List<OptimizationResult>();

			double overallProgress = 0;
			int runNo = 0;

			SystemProgressUpdate progressCallback = (currentItem, totalItems, currentTime) =>
			{
				double currentRunProgress = (double)currentItem / totalItems;
				string currentRunProgressText = null;
				if (currentTime != DateTime.MinValue)
				{
					CultureInfo culture = BarUtils.GetCurrencyCulture(runSettings.AccountCurrency);
					currentRunProgressText = "Current Run Progress: " + currentTime.ToString(culture.DateTimeFormat);
				}
				UpdateProgress(null, overallProgress + (currentRunProgress / MaxRuns), currentRunProgressText, currentRunProgress);
			};

			//	Get baseline results
			//runNo++;
			//OptimizationResult currentBest = RunSystem(runSettings, progressCallback);
			//ret.Add(currentBest);
			
			OptimizationResult currentBest = null;

			double[] currentParameters = _parametersToOptimize.Select(p => p.Value).ToArray();

			while (runNo < MaxRuns)
			{
				runNo++;

				string overallProgressText = string.Format("Optimization run {0} of {1}", runNo, MaxRuns);
				overallProgress = ((double)runNo - 1) / MaxRuns;
				UpdateProgress(overallProgressText, overallProgress, "Initializing...", 0);

				if (currentBest != null)
				{
					//	Choose parameters to use for next run
					double[] newParameters = GetRandomNeighbor(currentParameters, 1.0);
					runSettings.SystemParameters = new List<KeyValuePair<string, double>>();
					for (int i = 0; i < _parametersToOptimize.Count; i++)
					{
						runSettings.SystemParameters.Add(new KeyValuePair<string, double>(_parametersToOptimize[i].Name, newParameters[i]));
					}
					runSettings.SystemParameters.AddRange(_unOptimizedParameters.Select(p => new KeyValuePair<string, double>(p.Name, p.Value)));
				}

				OptimizationResult newResults = RunSystem(runSettings, progressCallback);

				if (currentBest == null ||
					EvaluateResults(newResults) >= EvaluateResults(currentBest))
				{
					currentBest = newResults;
					ret.Add(currentBest);
				}
				else
				{
					File.Delete(newResults.ResultsFile);
				}
			}

			//	Remove parameters that weren't optimized from the list so that they don't show up as columns in the optimization results
			HashSet<string> unoptimizedParameters = new HashSet<string>(OptimizationParameters.Where(p => p.NumSteps <= 1).Select(p => p.Name));
			foreach (var result in ret)
			{
				result.ParameterValues = result.ParameterValues.Where(p => !unoptimizedParameters.Contains(p.Key)).ToList();
			}

			return ret;
		}
		protected override bool ShowOptimizationSettings(SystemRunSettings runSettings, System.Windows.Forms.IWin32Window owner)
		{
			//	Don't pop up a dialog, just start the optimization
			return true;
			//return base.ShowOptimizationSettings(runSettings, owner);
		}
 protected override bool ShowOptimizationSettings(SystemRunSettings runSettings, System.Windows.Forms.IWin32Window owner)
 {
     return base.ShowOptimizationSettings(runSettings, owner);
 }
        public override List<OptimizationResult> RunOptimization(SystemRunSettings runSettings)
        {
            var optimizationResults = new List<OptimizationResult>();
            int[] optProgress = new int[OptimizationParameters.Count];
            Dictionary<string, double> paramDict = new Dictionary<string, double>(OptimizationParameters.Count);
            int runNo = 0;
            while (true)
            {
                runNo++;

                int totalRuns = 1;

                for (int i = 0; i < OptimizationParameters.Count; i++)
                {
                    SystemParameterInfo param = OptimizationParameters[i];
                    totalRuns *= param.NumSteps;
                    double currentValue;
                    if (param.NumSteps > 1)
                    {
                        double stepSize = (double)((Decimal)(param.High - param.Low) / (Decimal)(param.NumSteps - 1));
                        currentValue = param.Low + optProgress[i] * stepSize;
                    }
                    else
                    {
                        currentValue = param.Low;
                    }
                    paramDict[param.Name] = currentValue;
                }

                string overallProgressText = string.Format("Optimization run {0} of {1}", runNo, totalRuns);

                double overallProgress = ((double)runNo - 1) / totalRuns;
                UpdateProgress(overallProgressText, overallProgress, "Initializing...", 0);

                runSettings.SystemParameters = paramDict.ToList();
                OptimizationResult result = RunSystem(runSettings, (currentItem, totalItems, currentTime) =>
                {
                    double currentRunProgress = (double)currentItem / totalItems;
                    string currentRunProgressText = null;
                    if (currentTime != DateTime.MinValue)
                    {
                        CultureInfo culture = BarUtils.GetCurrencyCulture(runSettings.AccountCurrency);
                        currentRunProgressText = "Current Run Progress: " + currentTime.ToString(culture.DateTimeFormat);
                    }
                    UpdateProgress(null, overallProgress + (currentRunProgress / totalRuns), currentRunProgressText, currentRunProgress);
                });

                if (!runSettings.SaveOptimizationResults)
                {
                    File.Delete(result.ResultsFile);
                }

                optimizationResults.Add(result);

                bool done = true;
                for (int i = 0; i < optProgress.Length; i++)
                {
                    optProgress[i]++;
                    if (optProgress[i] < OptimizationParameters[i].NumSteps)
                    {
                        done = false;
                        break;
                    }
                    else
                    {
                        optProgress[i] = 0;
                    }
                }

                if (done)
                {
                    break;
                }
            }

            //	Remove parameters that weren't optimized from the list so that they don't show up as columns in the optimization results
            HashSet<string> unoptimizedParameters = new HashSet<string>(OptimizationParameters.Where(p => p.NumSteps <= 1).Select(p => p.Name));
            foreach (var result in optimizationResults)
            {
                result.ParameterValues = result.ParameterValues.Where(p => !unoptimizedParameters.Contains(p.Key)).ToList();
            }

            return optimizationResults;
        }
 protected override void LoadOptimizationSettingsFromFile(SystemRunSettings runSettings, string filename)
 {
     base.LoadOptimizationSettingsFromFile(runSettings, filename);
 }