Ejemplo n.º 1
0
        /// <summary>
        /// Сортировка списка с результатами оптимизации
        /// </summary>
        /// <param name="results">Текущая коллекция с результатами</param>
        /// <param name="order">Направленность сортировки</param>
        /// <param name="sortingFlags">Список коэффициентов сортировки</param>
        /// <param name="sortMethod">Метод сортировки</param>
        /// <returns></returns>
        public static IEnumerable <OptimisationResult> SortOptimisations(this IEnumerable <OptimisationResult> results,
                                                                         OrderBy order, IEnumerable <SortBy> sortingFlags)
        {
            // Получаем уникальный список флагов для сортировки
            sortingFlags = sortingFlags.Distinct();
            // Проверяем наличие флагов
            if (sortingFlags.Count() == 0)
            {
                return(null);
            }
            // Если флаг один то сортируем чисто по этому показателю
            if (sortingFlags.Count() == 1)
            {
                if (order == GetSortingDirection(sortingFlags.ElementAt(0)))
                {
                    return(results.OrderBy(x => x.GetResult(sortingFlags.ElementAt(0))));
                }
                else
                {
                    return(results.OrderByDescending(x => x.GetResult(sortingFlags.ElementAt(0))));
                }
            }

            // Формируем границы минимум и максимум по переданным флагам оптимизации
            Dictionary <SortBy, MinMax> Borders = sortingFlags.ToDictionary(x => x, x => new MinMax {
                Max = double.MinValue, Min = double.MaxValue
            });

            #region create Borders min max dictionary
            // Цикл по списку проходов оптимизаций
            for (int i = 0; i < results.Count(); i++)
            {
                // Цикл по флагам сортировки
                foreach (var item in sortingFlags)
                {
                    // получаем значение текущего коэффициента
                    double value = results.ElementAt(i).GetResult(item);
                    MinMax mm    = Borders[item];
                    // Задаем значения минимум и максимум
                    mm.Max        = Math.Max(mm.Max, value);
                    mm.Min        = Math.Min(mm.Min, value);
                    Borders[item] = mm;
                }
            }
            #endregion

            // Вес взвешенной суммы нормированных коэффициентов
            double coef = (1.0 / Borders.Count);

            // Переводим список результатов оптимизации к массиву типа List
            // Так как с ним быстрее работать
            List <OptimisationResult> listOfResults = results.ToList();
            // Цикл по результатам оптимизации
            for (int i = 0; i < listOfResults.Count; i++)
            {
                // Присваиваем значение текущему коэффициент
                OptimisationResult data = listOfResults[i];
                // Зануляем текущий коэффициент сортировки
                data.SortBy = 0;
                // Проводим цикл сформированным границам максимумов и минимумов
                foreach (var item in Borders)
                {
                    // Получаем значение текущего результата
                    double value = listOfResults[i].GetResult(item.Key);
                    MinMax mm    = item.Value;

                    // Если минимум меньше нуля - сдвигаемвсе данные на велечину отрицательного минимума
                    if (mm.Min < 0)
                    {
                        value  += Math.Abs(mm.Min);
                        mm.Max += Math.Abs(mm.Min);
                    }

                    // Если максимум больше нуля - делаем подсччеты
                    if (mm.Max > 0)
                    {
                        // В зависимости от метода сортировки - высчитываем коэффициент
                        if (GetSortingDirection(item.Key) == OrderBy.Descending)
                        {
                            // высчитываем коэффициент для сортировки по убыванию
                            data.SortBy += (1 - value / mm.Max) * coef;
                        }
                        else
                        {
                            // Высчитываем коэффициент для сортировки по возрастанию
                            data.SortBy += value / mm.Max * coef;
                        }
                    }
                }
                // Замещаем значение текущего коэффициента коэффициентом с параметром сортировки
                listOfResults[i] = data;
            }

            // Сортируем в зависимости от переданного типа сортировки
            if (order == OrderBy.Ascending)
            {
                return(listOfResults.OrderBy(x => x.SortBy));
            }
            else
            {
                return(listOfResults.OrderByDescending(x => x.SortBy));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Запись конкретного оптимизационного прозода
        /// </summary>
        /// <param name="resultItem">Значение оптимизационного прохода</param>
        /// <param name="writer">Писатель</param>
        private static void WriteResultItem(OptimisationResult resultItem, XmlTextWriter writer)
        {
            // Запись коэффициентов
            #region Coefficients
            writer.WriteStartElement("Coefficients");

            // Пишем VaR
            #region VaR
            writer.WriteStartElement("VaR");

            WriteItem(writer, "90", resultItem.GetResult(SortBy.Q_90).ToString()); // Квантиль 90
            WriteItem(writer, "95", resultItem.GetResult(SortBy.Q_95).ToString()); // Квантиль 95
            WriteItem(writer, "99", resultItem.GetResult(SortBy.Q_99).ToString()); // Квантиль 99
            WriteItem(writer, "Mx", resultItem.GetResult(SortBy.Mx).ToString());   // Среднее по PL
            WriteItem(writer, "Std", resultItem.GetResult(SortBy.Std).ToString()); // среднеквадратическое отклонение по PL

            writer.WriteEndElement();
            #endregion

            // Пишем параметры PL / DD - крайние точки
            #region Max PL DD
            writer.WriteStartElement("Max_PL_DD");
            WriteItem(writer, "Profit", resultItem.GetResult(SortBy.MaxProfit).ToString());                                    // Суммарная прибыль
            WriteItem(writer, "DD", resultItem.GetResult(SortBy.MaxDD).ToString());                                            // Суммарный убыток
            WriteItem(writer, "Total Profit Trades", ((int)resultItem.GetResult(SortBy.MaxProfitTotalTrades)).ToString());     // Общее кол - во прибыльных трейдов
            WriteItem(writer, "Total Loose Trades", ((int)resultItem.GetResult(SortBy.MaxDDTotalTrades)).ToString());          // Общее кол - во убыточных трейдов
            WriteItem(writer, "Consecutive Wins", ((int)resultItem.GetResult(SortBy.MaxProfitConsecutivesTrades)).ToString()); // Прибыльных трейдов подряд
            WriteItem(writer, "Consecutive Loose", ((int)resultItem.GetResult(SortBy.MaxDDConsecutivesTrades)).ToString());    // Убыточный трейдов подряд
            writer.WriteEndElement();
            #endregion

            // Пишем результаты торгов по дням
            #region Trading_Days

            // Метод пишуший результаты торгов
            void AddDay(string Day, double Profit, double DD, int ProfitTrades, int DDTrades)
            {
                writer.WriteStartElement(Day);

                WriteItem(writer, "Profit", Profit.ToString());                        // прибыли
                WriteItem(writer, "DD", DD.ToString());                                // убытки
                WriteItem(writer, "Number Of Profit Trades", ProfitTrades.ToString()); // кол - во прибыльных трейдов
                WriteItem(writer, "Number Of Loose Trades", DDTrades.ToString());      // кол - во убыточных трейдов

                writer.WriteEndElement();
            }

            writer.WriteStartElement("Trading_Days");

            // Пн
            AddDay("Mn", resultItem.GetResult(SortBy.AverageDailyProfit_Mn),
                   resultItem.GetResult(SortBy.AverageDailyDD_Mn),
                   (int)resultItem.GetResult(SortBy.AverageDailyProfitTrades_Mn),
                   (int)resultItem.GetResult(SortBy.AverageDailyDDTrades_Mn));
            // Вт
            AddDay("Tu", resultItem.GetResult(SortBy.AverageDailyProfit_Tu),
                   resultItem.GetResult(SortBy.AverageDailyDD_Tu),
                   (int)resultItem.GetResult(SortBy.AverageDailyProfitTrades_Tu),
                   (int)resultItem.GetResult(SortBy.AverageDailyDDTrades_Tu));
            // Ср
            AddDay("We", resultItem.GetResult(SortBy.AverageDailyProfit_We),
                   resultItem.GetResult(SortBy.AverageDailyDD_We),
                   (int)resultItem.GetResult(SortBy.AverageDailyProfitTrades_We),
                   (int)resultItem.GetResult(SortBy.AverageDailyDDTrades_We));
            // Чт
            AddDay("Th", resultItem.GetResult(SortBy.AverageDailyProfit_Th),
                   resultItem.GetResult(SortBy.AverageDailyDD_Th),
                   (int)resultItem.GetResult(SortBy.AverageDailyProfitTrades_Th),
                   (int)resultItem.GetResult(SortBy.AverageDailyDDTrades_Th));
            // Пт
            AddDay("Fr", resultItem.GetResult(SortBy.AverageDailyProfit_Fr),
                   resultItem.GetResult(SortBy.AverageDailyDD_Fr),
                   (int)resultItem.GetResult(SortBy.AverageDailyProfitTrades_Fr),
                   (int)resultItem.GetResult(SortBy.AverageDailyDDTrades_Fr));

            writer.WriteEndElement();
            #endregion

            // Пишем остальные коэййициенты
            WriteItem(writer, "Custom", resultItem.GetResult(SortBy.Custom).ToString());
            WriteItem(writer, "Payoff", resultItem.GetResult(SortBy.Payoff).ToString());
            WriteItem(writer, "Profit factor", resultItem.GetResult(SortBy.ProfitFactor).ToString());
            WriteItem(writer, "Average Profit factor", resultItem.GetResult(SortBy.AverageProfitFactor).ToString());
            WriteItem(writer, "Recovery factor", resultItem.GetResult(SortBy.RecoveryFactor).ToString());
            WriteItem(writer, "Average Recovery factor", resultItem.GetResult(SortBy.AverageRecoveryFactor).ToString());
            WriteItem(writer, "Total trades", ((int)resultItem.GetResult(SortBy.TotalTrades)).ToString());
            WriteItem(writer, "PL", resultItem.GetResult(SortBy.PL).ToString());
            WriteItem(writer, "DD", resultItem.GetResult(SortBy.DD).ToString());
            WriteItem(writer, "Altman Z Score", resultItem.GetResult(SortBy.AltmanZScore).ToString());

            writer.WriteEndElement();
            #endregion

            // Пишем коэффициенты робота
            #region Bot params
            foreach (var item in resultItem.report.BotParams)
            {
                WriteItem(writer, item.Key, item.Value);
            }
            #endregion
        }