private void StartOptimisation(OptimiserInputData optimiserInputData, bool isAppend, string dirPrefix)
        {
            if ((optimiserInputData.HistoryBorders.Count == 0 && optimiserInputData.ForwardBorders.Count == 0))
            {
                ThrowException("Fill in date borders");
                OnPropertyChanged("ResumeEnablingTogle");
                return;
            }

            if (Optimiser.TerminalManager.IsActive)
            {
                ThrowException("Terminal already running");
                return;
            }

            if (optimiserInputData.OptimisationMode == ENUM_OptimisationMode.Disabled)
            {
                StartTest(optimiserInputData);
                return;
            }

            if (!isAppend)
            {
                var dir = workingDirectory.GetOptimisationDirectory(optimiserInputData.Symb,
                                                                    Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot),
                                                                    dirPrefix, Optimiser.Name);
                List <FileInfo> data = dir.GetFiles().ToList();
                data.ForEach(x => x.Delete());
                List <DirectoryInfo> dirData = dir.GetDirectories().ToList();
                dirData.ForEach(x => x.Delete());
            }

            Optimiser.CloseSettingsWindow();

            try
            {
                DirectoryInfo cachDir = Optimiser.TerminalManager.TerminalChangeableDirectory
                                        .GetDirectory("Tester")
                                        .GetDirectory("cache", true);
                DirectoryInfo cacheCopy = workingDirectory.Tester.GetDirectory("cache", true);
                cacheCopy.GetFiles().ToList().ForEach(x => x.Delete());
                cachDir.GetFiles().ToList()
                .ForEach(x => x.MoveTo(Path.Combine(cacheCopy.FullName, x.Name)));

                ClearResults();
                Optimiser.ClearOptimiser();

                int ind = optimiserInputData.BotParams.FindIndex(x => x.Variable == Fixed_Input_Settings.Params[InputParamName.CloseTerminalFromBot]);
                if (ind > -1)
                {
                    var item = optimiserInputData.BotParams[ind];
                    item.Value      = "true";
                    item.IsOptimize = false;
                    optimiserInputData.BotParams[ind] = item;
                }
                var botParams = optimiserInputData.BotParams.ToList(); // Copy expert settings

                Optimiser.Start(optimiserInputData,
                                Path.Combine(terminalDirectory.Common.FullName,
                                             $"{Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot)}_Report.xml"), dirPrefix);

                SetFileManager fileManager = new SetFileManager(
                    Path.Combine(workingDirectory.GetOptimisationDirectory(optimiserInputData.Symb,
                                                                           Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot),
                                                                           dirPrefix, Optimiser.Name).FullName, "OptimisationSettings.set"), true)
                {
                    Params = botParams
                };
                fileManager.SaveParams();

                Optimiser.TerminalManager.WaitForStop();
            }
            catch (Exception e)
            {
                Optimiser.Stop();
                throw e;
            }
        }
        public override void Start(OptimiserInputData optimiserInputData, string PathToResultsFile, string dirPrefix)
        {
            if (IsOptimisationInProcess || TerminalManager.IsActive)
            {
                throw new Exception("Optimisation already in process or terminal is busy");
            }
            // Устанавливает статус оптимизации и переключатель
            OnProcessStatus("Start optimisation", 0);
            IsOptimisationInProcess = true;

            // Проверить доступность папки к результатом оптимизации
            if (string.IsNullOrEmpty(PathToResultsFile) ||
                string.IsNullOrWhiteSpace(PathToResultsFile))
            {
                throw new ArgumentException("Path to results file is null or empty");
            }

            // Проверить количество границ исторических оптимизаций
            if (optimiserInputData.HistoryBorders.Count == 0)
            {
                throw new ArgumentException("There are no history optimisations date borders");
            }
            // Проверить количество границ исторических оптимизаций
            if (optimiserInputData.ForwardBorders.Count == 0)
            {
                throw new ArgumentException("There are no forward optimisations date borders");
            }

            // Проверить флаги сортировки
            if (optimiserInputData.SortingFlags.Count() == 0)
            {
                throw new ArgumentException("There are no sorting params");
            }

            // Установка рабочей директории оптимизатора
            OptimiserWorkingDirectory = workingDirectory.GetOptimisationDirectory(optimiserInputData.Symb,
                                                                                  Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot), dirPrefix, Name).FullName;

            // Уладение существующего файла с резальтатами оптимизаций
            if (File.Exists(PathToResultsFile))
            {
                File.Delete(PathToResultsFile);
            }

            // Установка настроек оптимизатора
            PathToBot = optimiserInputData.RelativePathToBot;
            Currency  = optimiserInputData.Currency;
            Balance   = optimiserInputData.Balance;
            Laverage  = optimiserInputData.Laverage;

            // Создание (*set) файла и созранение в него настроек робота
            string setFileName = CommonMethods.SaveExpertSettings(Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot),
                                                                  optimiserInputData.BotParams, TerminalManager.TerminalChangeableDirectory);

            // Выбор шага для прогресс бара
            double step = 100.0 / optimiserInputData.HistoryBorders.Count;
            // Счетчик итераций прогресс бара
            int i = 1;

            // Config
            Config configFile = CommonMethods.GetConfig(optimiserInputData,
                                                        setFileName,
                                                        optimiserInputData.HistoryBorders[0],
                                                        TerminalManager.TerminalChangeableDirectory,
                                                        Path.Combine(workingDirectory.WDRoot.FullName, $"{TerminalManager.TerminalID}.ini"));

            Dictionary <DateBorders, DateBorders> historyToForwardBorders =
                DateBorders.CompareHistoryToForward(optimiserInputData.HistoryBorders,
                                                    optimiserInputData.ForwardBorders);

            Dictionary <DateBorders, KeyValuePair <DateBorders, IEnumerable <ParamsItem> > > TestInputData =
                new Dictionary <DateBorders, KeyValuePair <DateBorders, IEnumerable <ParamsItem> > >();

            foreach (var item in optimiserInputData.HistoryBorders)
            {
                // Выходим из метода если вдруг остановили оптимизацию извне
                if (!IsOptimisationInProcess)
                {
                    return;
                }

                // Обновляем прогресс бар
                OnProcessStatus("Optimisation", step * i++);

                configFile.Tester.FromDate = item.From;
                configFile.Tester.ToDate   = item.Till;

                // Run
                if (!CommonMethods.RunTester(configFile, TerminalManager))
                {
                    continue;
                }

                // Чтение файла с отчетом и удаление его после прочтения
                List <OptimisationResult> results = new List <OptimisationResult>();
                if (!CommonMethods.ReadFile(results, PathToResultsFile, Currency, Balance, Laverage, PathToBot))
                {
                    continue;
                }
                // Устанавливаем для всех прочитанных результатов единые границы дат оптимизаций
                results.ForEach(x =>
                {
                    x.report.DateBorders = item;
                    AllOptimisationResults.Add(x);
                });

                var test_data = FilterResults(results, historyToForwardBorders[item],
                                              optimiserInputData.CompareData,
                                              optimiserInputData.SortingFlags);
                if (test_data.HasValue)
                {
                    TestInputData.Add(item, test_data.Value);
                }
            }

            // Выбор шага для прогресс бара
            step = 100.0 / TestInputData.Count;
            // Счетчик итераций прогресс бара
            i = 1;
            // Обновляем прогресс бар
            OnProcessStatus("Tests", 0);

            configFile.Tester.Optimization     = ENUM_OptimisationMode.Disabled;
            configFile.Tester.ShutdownTerminal = true;
            configFile.Tester.Model            =
                (Settings.IsTickTest ? ENUM_Model.Every_tick_based_on_real_ticks : ENUM_Model.OHLC_1_minute);
            foreach (var item in TestInputData)
            {
                // Выходим из метода если вдруг остановили оптимизацию извне
                if (!IsOptimisationInProcess)
                {
                    return;
                }

                // Обновляем прогресс бар
                OnProcessStatus("Tests", step * i++);

                Test(item.Key, item.Value.Key, item.Value.Value, configFile, PathToResultsFile);
            }

            CommonMethods.SaveExpertSettings(Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot),
                                             optimiserInputData.BotParams, TerminalManager.TerminalChangeableDirectory);

            // Переключение статуса оптимизаций на завершенный и вызов соответствующего события
            IsOptimisationInProcess = false;
            OnOptimisationProcessFinished(this);
        }