/// <summary> /// Сортируем загруженный отчет /// </summary> /// <param name="borders">Выбранный диаппазон дат</param> /// <param name="sortingFlags">Выбранные параметры сортировки</param> public async void SortResults(DateBorders borders, IEnumerable <SortBy> sortingFlags) { void UpdatePB(string status, double progress) { if (Optimiser.IsOptimisationInProcess) { return; } if (Optimiser.TerminalManager.IsActive) { return; } PBUpdate(status, progress); } UpdatePB("Sorting results", 100); await Task.Run(() => { AllOptimisationResults.AllOptimisationResults[borders] = AllOptimisationResults.AllOptimisationResults[borders].SortOptimisations(OrderBy.Descending, sortingFlags).ToList(); OnPropertyChanged("SortedResults"); }); UpdatePB(null, 0); }
/// <summary> /// Фильтруем результаты оптимизаций /// </summary> /// <param name="borders">Выбранный диаппазон дат</param> /// <param name="compareData">Сопостовляемые флаги</param> public async void FilterResults(DateBorders borders, IDictionary <SortBy, KeyValuePair <CompareType, double> > compareData) { void UpdatePB(string status, double progress) { if (Optimiser.IsOptimisationInProcess) { return; } if (Optimiser.TerminalManager.IsActive) { return; } PBUpdate(status, progress); } UpdatePB("Filter Results", 100); await Task.Run(() => { AllOptimisationResults.AllOptimisationResults[borders] = AllOptimisationResults.AllOptimisationResults[borders].FiltreOptimisations(compareData).ToList(); OnPropertyChanged("FilteredResults"); }); UpdatePB(null, 0); }
private KeyValuePair <DateBorders, IEnumerable <ParamsItem> >?FilterResults(List <OptimisationResult> results, DateBorders borders, IDictionary <SortBy, KeyValuePair <CompareType, double> > CompareData, IEnumerable <SortBy> SortingFlags) { // Фильтрация results = results.FiltreOptimisations(CompareData).ToList(); if (results.Count == 0) { return(null); } // Первая сортировка results = results.SortOptimisations(OrderBy.Descending, SortingFlags).ToList(); // Выбор 100 лучших результатов и повторная сортировка results = results.GetRange(0, Math.Min(100, results.Count)); results = results.SortOptimisations(OrderBy.Descending, new[] { Settings.SecondSorter }).ToList(); // Подготовка параметров и возвращение результатов return(new KeyValuePair <DateBorders, IEnumerable <ParamsItem> >(borders, results.First().report.BotParams .Select(x => new ParamsItem { Variable = x.Key, Value = x.Value }))); }
/// <summary> /// Созраняем отчет оптимизаций за выбранные даты в (*.csv) файл /// </summary> /// <param name="dateBorders">Выбранные временные границы</param> /// <param name="pathToSavingFile">Путь к созраняемому файлу</param> public void SaveToCSVOptimisations(DateBorders dateBorders, string pathToSavingFile) { List <View_Model.ReportItem> results = new List <View_Model.ReportItem>(); if (dateBorders != null) { results.AddRange(AllOptimisationResults.AllOptimisationResults[dateBorders].Select(x => (View_Model.ReportItem)x)); } CreateCsv(results, Path.Combine(Path.GetDirectoryName(pathToSavingFile), $"{Path.GetFileNameWithoutExtension(pathToSavingFile)}.csv"), true); }
public void Calculate(DateTime From, DateTime Till, uint history, uint forward) { if (From >= Till) { throw new ArgumentException("Date From must be less then date Till"); } List <KeyValuePair <OptimisationType, DateTime[]> > data = new List <KeyValuePair <OptimisationType, DateTime[]> >(); OptimisationType type = OptimisationType.History; DateTime _history = From; DateTime _forward = From.AddDays(history + 1); DateTime CalcEndDate() { return(type == OptimisationType.History ? _history.AddDays(history) : _forward.AddDays(forward)); } while (CalcEndDate() <= Till) { DateTime from = type == OptimisationType.History ? _history : _forward; data.Add(new KeyValuePair <OptimisationType, DateTime[]>(type, new DateTime[2] { from, CalcEndDate() })); if (type == OptimisationType.History) { _history = _history.AddDays(forward + 1); } else { _forward = _forward.AddDays(forward + 1); } type = type == OptimisationType.History ? OptimisationType.Forward : OptimisationType.History; } if (data.Count == 0) { throw new ArgumentException("Can`t create any date borders with setted In sample (History) step"); } DateBorders?.Invoke(data); }
/// <summary> /// Метод получающий список дат (коридоры оптимизаций) для тестера и оптимизатора /// </summary> /// <param name="pathToFile">Путь к файлу предварительно созданному методом SaveBorders данного класса</param> /// <returns>Список оптимизационных проходов</returns> public static List <KeyValuePair <DateBorders, OptimisationType> > GetBorders(string pathToFile) { XmlDocument document = new XmlDocument(); document.Load(pathToFile); List <KeyValuePair <DateBorders, OptimisationType> > borders = new List <KeyValuePair <DateBorders, OptimisationType> >(); foreach (XmlNode item in document["Borders"].ChildNodes) { DateBorders borderItem = new DateBorders( DateTime.ParseExact(item["From"].InnerText, "dd.MM.yyyy HH:mm:ss.fff", null), DateTime.ParseExact(item["Till"].InnerText, "dd.MM.yyyy HH:mm:ss.fff", null)); OptimisationType type = (OptimisationType)Enum.Parse(typeof(OptimisationType), item["Type"].InnerText); borders.Add(new KeyValuePair <DateBorders, OptimisationType>(borderItem, type)); } return(borders); }
public static Config GetConfig(OptimiserInputData optimiserInputData, string setFileName, DateBorders dateBorders, DirectoryInfo terminalChangeableDirectory, string pathToNewIniFile) { Config config = new Config(terminalChangeableDirectory.GetDirectory("config") .GetFiles("common.ini") .First().FullName) .DublicateFile(pathToNewIniFile); config.Tester.Currency = optimiserInputData.Currency; config.Tester.Deposit = optimiserInputData.Balance; config.Tester.ExecutionMode = optimiserInputData.ExecutionDelay; config.Tester.Expert = optimiserInputData.RelativePathToBot; config.Tester.ExpertParameters = setFileName; config.DeleteKey(ENUM_SectionType.Tester, "ForwardDate"); config.Tester.ForwardMode = ENUM_ForvardMode.Disabled; config.Tester.FromDate = dateBorders.From; config.Tester.Leverage = $"1:{optimiserInputData.Laverage}"; config.Tester.Model = optimiserInputData.Model; config.Tester.Optimization = optimiserInputData.OptimisationMode; config.Tester.OptimizationCriterion = ENUM_OptimisationCriteria.Balance__Profit_factor; config.Tester.Period = optimiserInputData.TF; config.DeleteKey(ENUM_SectionType.Tester, "Report"); if (optimiserInputData.BotParams.Any(x => x.Variable == Fixed_Input_Settings.Params[InputParamName.CloseTerminalFromBot]) && optimiserInputData.OptimisationMode != ENUM_OptimisationMode.Disabled) { config.Tester.ShutdownTerminal = false; } else { config.Tester.ShutdownTerminal = true; } config.Tester.Symbol = optimiserInputData.Symb; config.Tester.ToDate = dateBorders.Till; return(config); }
private void Test(DateBorders border_history, DateBorders border_forward, IEnumerable <ParamsItem> botParams, Config config, string pathToReportFile) { // History test CommonMethods.SaveExpertSettings(Path.GetFileNameWithoutExtension(config.Tester.Expert), botParams.ToList(), TerminalManager.TerminalChangeableDirectory); List <OptimisationResult> data = new List <OptimisationResult>(); void tester(List <OptimisationResult> collection, DateBorders borders) { if (borders == null) { return; } config.Tester.FromDate = borders.From; config.Tester.ToDate = borders.Till; if (CommonMethods.RunTester(config, TerminalManager) && CommonMethods.ReadFile(data, pathToReportFile, Currency, Balance, Laverage, PathToBot)) { var item = data.First(); if (item.report.BotParams.Count == 0) { item.report.BotParams = botParams.ToDictionary(x => x.Variable, x => x.Value); } item.report.DateBorders = borders; collection.Add(item); } data.Clear(); } tester(HistoryOptimisations, border_history); tester(ForwardOptimisations, border_forward); }
/// <summary> /// Запуск тестов /// </summary> /// <param name="optimiserInputData">Взодные данные для тестера</param> public async void StartTest(OptimiserInputData optimiserInputData) { // Проверка не запущен ли терминалл if (Optimiser.TerminalManager.IsActive) { ThrowException("Terminal already running"); return; } // Задаем диаппазон дат #region From/Forward/To DateTime Forward = new DateTime(); DateTime ToDate = Forward; DateTime FromDate = Forward; // Проверка на количество переданных дат. Максимум одна историческая и одна форвардная if (optimiserInputData.HistoryBorders.Count > 1 || optimiserInputData.ForwardBorders.Count > 1) { ThrowException("For test there mast be from 1 to 2 date borders"); OnPropertyChanged("ResumeEnablingTogle"); return; } // Если передана и историческая и форвардная даты if (optimiserInputData.HistoryBorders.Count == 1 && optimiserInputData.ForwardBorders.Count == 1) { // Тестируем на корректность заданного промежутка DateBorders _Forward = optimiserInputData.ForwardBorders[0]; DateBorders _History = optimiserInputData.HistoryBorders[0]; if (_History > _Forward) { ThrowException("History optimisation mast be less than Forward"); OnPropertyChanged("ResumeEnablingTogle"); return; } // Запоминаем даты Forward = _Forward.From; FromDate = _History.From; ToDate = (_History.Till < _Forward.Till ? _Forward.Till : _History.Till); } else // Если передана лишь форвардная или же лишь историческая дата { // Созраняем их и считаем что это была историческая дата (даже если была передана форвардная) if (optimiserInputData.HistoryBorders.Count > 0) { FromDate = optimiserInputData.HistoryBorders[0].From; ToDate = optimiserInputData.HistoryBorders[0].Till; } else { FromDate = optimiserInputData.ForwardBorders[0].From; ToDate = optimiserInputData.ForwardBorders[0].Till; } } #endregion PBUpdate("Start test", 100); // Запукаем тест во вторичном потоке await Task.Run(() => { try { // Создаем файл с настройкамит эксперта #region Create (*.set) file FileInfo file = new FileInfo(Path.Combine(Optimiser .TerminalManager .TerminalChangeableDirectory .GetDirectory("MQL5") .GetDirectory("Profiles") .GetDirectory("Tester") .FullName, $"{Path.GetFileNameWithoutExtension(optimiserInputData.RelativePathToBot)}.set")); List <ParamsItem> botParams = new List <ParamsItem>(GetBotParams(optimiserInputData.RelativePathToBot, false)); // Заполняем настройки эксперта теми что были введены в графическом интерфейсе for (int i = 0; i < optimiserInputData.BotParams.Count; i++) { var item = optimiserInputData.BotParams[i]; int ind = botParams.FindIndex(x => x.Variable == item.Variable); if (ind != -1) { var param = botParams[ind]; param.Value = item.Value; botParams[ind] = param; } } // Созраянем настройки в файл SetFileManager setFile = new SetFileManager(file.FullName, false) { Params = botParams }; setFile.SaveParams(); #endregion // Создаем конфиг терминала #region Create config file Config config = new Config(Optimiser.TerminalManager .TerminalChangeableDirectory .GetDirectory("config") .GetFiles("common.ini") .First().FullName); config = config.DublicateFile(Path.Combine(workingDirectory.WDRoot.FullName, $"{Optimiser.TerminalManager.TerminalID}.ini")); config.Tester.Currency = optimiserInputData.Currency; config.Tester.Deposit = optimiserInputData.Balance; config.Tester.ExecutionMode = optimiserInputData.ExecutionDelay; config.Tester.Expert = optimiserInputData.RelativePathToBot; config.Tester.ExpertParameters = setFile.FileInfo.Name; config.Tester.ForwardMode = (Forward == new DateTime() ? ENUM_ForvardMode.Disabled : ENUM_ForvardMode.Custom); if (config.Tester.ForwardMode == ENUM_ForvardMode.Custom) { config.Tester.ForwardDate = Forward; } else { config.DeleteKey(ENUM_SectionType.Tester, "ForwardDate"); } config.Tester.FromDate = FromDate; config.Tester.ToDate = ToDate; config.Tester.Leverage = $"1:{optimiserInputData.Laverage}"; config.Tester.Model = optimiserInputData.Model; config.Tester.Optimization = ENUM_OptimisationMode.Disabled; config.Tester.Period = optimiserInputData.TF; config.Tester.ShutdownTerminal = false; config.Tester.Symbol = optimiserInputData.Symb; config.Tester.Visual = false; #endregion // Конфигурируем терминалл и запускаем его Optimiser.TerminalManager.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal; Optimiser.TerminalManager.Config = config; Optimiser.TerminalManager.Run(); // Ожидаем закрытие терминала Optimiser.TerminalManager.WaitForStop(); } catch (Exception e) { ThrowException(e.Message); } OnPropertyChanged("StopTest"); }); }
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); }