/// <summary>
        /// Sets the indicator overview and warning message.
        /// </summary>
        private void SetIndicatorNotification(Indicator indicator)
        {
            // Warning message.
            _warningMessage = indicator.WarningMessage;
            LblIndicatorWarning.Visible = !string.IsNullOrEmpty(_warningMessage);

            // Set description.
            indicator.SetDescription(SlotType);
            _description = "Long position:" + Environment.NewLine;
            if (SlotType == SlotTypes.Open)
            {
                _description += "   Open a long position " + indicator.EntryPointLongDescription + "." +
                                Environment.NewLine + Environment.NewLine;
                _description += "Short position:" + Environment.NewLine;
                _description += "   Open a short position " + indicator.EntryPointShortDescription + ".";
            }
            else if (SlotType == SlotTypes.OpenFilter)
            {
                _description += "   Open a long position when " + indicator.EntryFilterLongDescription + "." +
                                Environment.NewLine + Environment.NewLine;
                _description += "Short position:" + Environment.NewLine;
                _description += "   Open a short position when " + indicator.EntryFilterShortDescription + ".";
            }
            else if (SlotType == SlotTypes.Close)
            {
                _description += "   Close a long position " + indicator.ExitPointLongDescription + "." +
                                Environment.NewLine + Environment.NewLine;
                _description += "Short position:" + Environment.NewLine;
                _description += "   Close a short position " + indicator.ExitPointShortDescription + ".";
            }
            else
            {
                _description += "   Close a long position when " + indicator.ExitFilterLongDescription + "." +
                                Environment.NewLine + Environment.NewLine;
                _description += "Short position:" + Environment.NewLine;
                _description += "   Close a short position when " + indicator.ExitFilterShortDescription + ".";
            }

            for (int i = 0; i < 2; i++)
                if (indicator.IndParam.CheckParam[i].Caption == "Use previous bar value")
                    _description += Environment.NewLine + "-------------" + Environment.NewLine + "* Use the value of " +
                                    indicator.IndicatorName + " from the previous bar.";

            _toolTip.SetToolTip(LblIndicatorInfo, _description);
        }
Пример #2
0
        /// <summary>
        /// Generates a HTML report about the closing logic.
        /// </summary>
        StringBuilder ClosingLogicHTMLReport()
        {
            var sb = new StringBuilder();

            int    closingSlotNmb = Data.Strategy.CloseSlot;
            string indicatorName  = Data.Strategy.Slot[closingSlotNmb].IndicatorName;

            Indicator indClose = IndicatorStore.ConstructIndicator(indicatorName, SlotTypes.Close);

            indClose.IndParam = Data.Strategy.Slot[closingSlotNmb].IndParam;
            indClose.SetDescription(SlotTypes.Close);

            bool isGroups    = false;
            var  closegroups = new List <string>();

            if (Data.Strategy.CloseFilters > 0)
            {
                foreach (IndicatorSlot slot in Data.Strategy.Slot)
                {
                    if (slot.SlotType == SlotTypes.CloseFilter)
                    {
                        if (slot.LogicalGroup == "all" && Data.Strategy.CloseFilters > 1)
                        {
                            isGroups = true;
                        }

                        if (closegroups.Contains(slot.LogicalGroup))
                        {
                            isGroups = true;
                        }
                        else if (slot.LogicalGroup != "all")
                        {
                            closegroups.Add(slot.LogicalGroup);
                        }
                    }
                }
            }

            if (closegroups.Count == 0 && Data.Strategy.CloseFilters > 0)
            {
                closegroups.Add("all"); // If all the slots are in "all" group, adds "all" to the list.
            }
            // Long position
            string closeLong = "<p>" + Language.T("Close an existing long position") + " " + indClose.ExitPointLongDescription;

            if (Data.Strategy.CloseFilters == 0)
            {
                closeLong += ".</p>";
            }
            else if (Data.Strategy.CloseFilters == 1)
            {
                closeLong += " " + Language.T("when the following logic condition is satisfied") + ":</p>";
            }
            else if (isGroups)
            {
                closeLong += " " + Language.T("when") + ":</p>";
            }
            else
            {
                closeLong += " " + Language.T("when at least one of the following logic conditions is satisfied") + ":</p>";
            }

            sb.AppendLine(closeLong);

            // Close Filters
            if (Data.Strategy.CloseFilters > 0)
            {
                int groupnumb = 1;
                sb.AppendLine("<ul>");

                foreach (string group in closegroups)
                {
                    if (isGroups)
                    {
                        sb.AppendLine("<li>" + (groupnumb == 1 ? "" : Language.T("or") + " ") + Language.T("logical group [#] is satisfied").Replace("#", group) + ":");
                        sb.AppendLine("<ul>");
                        groupnumb++;
                    }

                    int indInGroup = 0;
                    for (int slot = closingSlotNmb + 1; slot < Data.Strategy.Slots; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup == group || Data.Strategy.Slot[slot].LogicalGroup == "all")
                        {
                            indInGroup++;
                        }
                    }

                    int indnumb = 1;
                    for (int slot = closingSlotNmb + 1; slot < Data.Strategy.Slots; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup != group && Data.Strategy.Slot[slot].LogicalGroup != "all")
                        {
                            continue;
                        }

                        Indicator indCloseFilter = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, SlotTypes.CloseFilter);
                        indCloseFilter.IndParam = Data.Strategy.Slot[slot].IndParam;
                        indCloseFilter.SetDescription(SlotTypes.CloseFilter);

                        if (isGroups)
                        {
                            if (indnumb < indInGroup)
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterLongDescription + "; " + Language.T("and") + "</li>");
                            }
                            else
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterLongDescription + ".</li>");
                            }
                        }
                        else
                        {
                            if (slot < Data.Strategy.Slots - 1)
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterLongDescription + "; " + Language.T("or") + "</li>");
                            }
                            else
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterLongDescription + ".</li>");
                            }
                        }
                        indnumb++;
                    }

                    if (isGroups)
                    {
                        sb.AppendLine("</ul>");
                        sb.AppendLine("</li>");
                    }
                }

                sb.AppendLine("</ul>");
            }

            // Short position
            string closeShort = "<p>" + Language.T("Close an existing short position") + " " + indClose.ExitPointShortDescription;

            if (Data.Strategy.CloseFilters == 0)
            {
                closeShort += ".</p>";
            }
            else if (Data.Strategy.CloseFilters == 1)
            {
                closeShort += " " + Language.T("when the following logic condition is satisfied") + ":</p>";
            }
            else if (isGroups)
            {
                closeShort += " " + Language.T("when") + ":</p>";
            }
            else
            {
                closeShort += " " + Language.T("when at least one of the following logic conditions is satisfied") + ":</p>";
            }

            sb.AppendLine(closeShort);

            // Close Filters
            if (Data.Strategy.CloseFilters > 0)
            {
                int groupnumb = 1;
                sb.AppendLine("<ul>");

                foreach (string group in closegroups)
                {
                    if (isGroups)
                    {
                        sb.AppendLine("<li>" + (groupnumb == 1 ? "" : Language.T("or") + " ") + Language.T("logical group [#] is satisfied").Replace("#", group) + ":");
                        sb.AppendLine("<ul>");
                        groupnumb++;
                    }

                    int indInGroup = 0;
                    for (int slot = closingSlotNmb + 1; slot < Data.Strategy.Slots; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup == group || Data.Strategy.Slot[slot].LogicalGroup == "all")
                        {
                            indInGroup++;
                        }
                    }

                    int indnumb = 1;
                    for (int slot = closingSlotNmb + 1; slot < Data.Strategy.Slots; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup != group && Data.Strategy.Slot[slot].LogicalGroup != "all")
                        {
                            continue;
                        }

                        Indicator indCloseFilter = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, SlotTypes.CloseFilter);
                        indCloseFilter.IndParam = Data.Strategy.Slot[slot].IndParam;
                        indCloseFilter.SetDescription(SlotTypes.CloseFilter);

                        if (isGroups)
                        {
                            if (indnumb < indInGroup)
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterShortDescription + "; " + Language.T("and") + "</li>");
                            }
                            else
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterShortDescription + ".</li>");
                            }
                        }
                        else
                        {
                            if (slot < Data.Strategy.Slots - 1)
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterShortDescription + "; " + Language.T("or") + "</li>");
                            }
                            else
                            {
                                sb.AppendLine("<li>" + indCloseFilter.ExitFilterShortDescription + ".</li>");
                            }
                        }
                        indnumb++;
                    }

                    if (isGroups)
                    {
                        sb.AppendLine("</ul>");
                        sb.AppendLine("</li>");
                    }
                }

                sb.AppendLine("</ul>");
            }

            return(sb);
        }
        /// <summary>
        /// Tests general parameters of a custom indicator.
        /// </summary>
        /// <returns>True, if the test succeed.</returns>
        public static bool CustomIndicatorFastTest(Indicator indicator, out string errorList)
        {
            bool isOk = true;

            var sb = new StringBuilder();

            sb.AppendLine("ERROR: Indicator test failed for the '" + indicator.IndicatorName + "' indicator.");

            // Tests the IndicatorName property.
            if (string.IsNullOrEmpty(indicator.IndicatorName))
            {
                sb.AppendLine("\tThe property 'IndicatorName' is not set.");
                isOk = false;
            }

            // Tests the PossibleSlots property.
            if (!indicator.TestPossibleSlot(SlotTypes.Open) &&
                !indicator.TestPossibleSlot(SlotTypes.OpenFilter) &&
                !indicator.TestPossibleSlot(SlotTypes.Close) &&
                !indicator.TestPossibleSlot(SlotTypes.CloseFilter))
            {
                sb.AppendLine("\tThe property 'PossibleSlots' is not set.");
                isOk = false;
            }

            // Tests the CustomIndicator property.
            if (!indicator.CustomIndicator)
            {
                sb.AppendLine("\tThe indicator '" + indicator.IndicatorName +
                              "' is not marked as custom. Set CustomIndicator = true;");
                isOk = false;
            }

            // Tests the SeparatedChartMaxValue properties.
            if (!indicator.SeparatedChart && indicator.SeparatedChartMaxValue != double.MinValue)
            {
                sb.AppendLine("\tSet SeparatedChart = true; or remove the property: SeparatedChartMaxValue = " +
                              indicator.SeparatedChartMaxValue.ToString(CultureInfo.InvariantCulture));
                isOk = false;
            }

            // Tests the SeparatedChartMinValue properties.
            if (!indicator.SeparatedChart && indicator.SeparatedChartMinValue != double.MaxValue)
            {
                sb.AppendLine("\tSet SeparatedChart = true; or remove the property: SeparatedChartMinValue = " +
                              indicator.SeparatedChartMinValue.ToString(CultureInfo.InvariantCulture));
                isOk = false;
            }

            // Tests the SpecialValues properties.
            if (!indicator.SeparatedChart && indicator.SpecialValues.Length > 0)
            {
                sb.AppendLine("\tSet SeparatedChart = true; or remove the property SpecialValues");
                isOk = false;
            }

            // Tests the IndParam properties.
            if (indicator.IndParam == null)
            {
                sb.AppendLine("\tThe property IndParam is not set. Set IndParam = new IndicatorParam();");
                isOk = false;
            }

            // Tests the IndParam.IndicatorName properties.
            if (indicator.IndParam.IndicatorName != indicator.IndicatorName)
            {
                sb.AppendLine(
                    "\tThe property IndParam.IndicatorName is not set. Set IndParam.IndicatorName = IndicatorName;");
                isOk = false;
            }

            // Tests the IndParam.SlotType properties.
            if (indicator.IndParam.SlotType != SlotTypes.NotDefined)
            {
                sb.AppendLine("\tThe property IndParam.SlotType is not set. Set IndParam.SlotType = slotType;");
                isOk = false;
            }

            // Tests the IndParam.ListParam properties.
            for (int iParam = 0; iParam < indicator.IndParam.ListParam.Length; iParam++)
            {
                ListParam listParam = indicator.IndParam.ListParam[iParam];
                if (!listParam.Enabled)
                    continue;

                if (string.IsNullOrEmpty(listParam.Caption))
                {
                    sb.AppendLine("\tThe property IndParam.ListParam[" + iParam + "].Caption is not set.");
                    isOk = false;
                }

                if (listParam.ItemList.Length == 0)
                {
                    sb.AppendLine("\tThe property IndParam.ListParam[" + iParam + "].ItemList is not set.");
                    isOk = false;
                }

                if (listParam.ItemList[listParam.Index] != listParam.Text)
                {
                    sb.AppendLine("\tThe property IndParam.ListParam[" + iParam + "].Text is wrong." +
                                  " Set " + "IndParam.ListParam[" + iParam + "].Text = IndParam.ListParam[" + iParam +
                                  "].ItemList[IndParam.ListParam[" + iParam + "].Index];");
                    isOk = false;
                }

                if (string.IsNullOrEmpty(listParam.ToolTip))
                {
                    sb.AppendLine("\tThe property IndParam.ListParam[" + iParam + "].ToolTip is not set.");
                    isOk = false;
                }
            }

            // Tests the IndParam.NumParam properties.
            for (int param = 0; param < indicator.IndParam.NumParam.Length; param++)
            {
                NumericParam numParam = indicator.IndParam.NumParam[param];
                if (!numParam.Enabled)
                    continue;

                if (string.IsNullOrEmpty(numParam.Caption))
                {
                    sb.AppendLine("\tThe property IndParam.NumParam[" + param + "].Caption is not set.");
                    isOk = false;
                }

                double value = numParam.Value;
                double min = numParam.Min;
                double max = numParam.Max;
                double point = numParam.Point;

                if (min > max)
                {
                    sb.AppendLine("\tIndParam.NumParam[" + param + "].Min > IndParam.NumParam[" + param + "].Max.");
                    isOk = false;
                }

                if (value > max)
                {
                    sb.AppendLine("\tIndParam.NumParam[" + param + "].Value > IndParam.NumParam[" + param + "].Max.");
                    isOk = false;
                }

                if (value < min)
                {
                    sb.AppendLine("\tIndParam.NumParam[" + param + "].Value < IndParam.NumParam[" + param + "].Min.");
                    isOk = false;
                }

                if (point < 0)
                {
                    sb.AppendLine("\tIndParam.NumParam[" + param + "].Point cannot be < 0");
                    isOk = false;
                }

                if (point > 6)
                {
                    sb.AppendLine("\tIndParam.NumParam[" + param + "].Point cannot be > 6");
                    isOk = false;
                }

                if (string.IsNullOrEmpty(numParam.ToolTip))
                {
                    sb.AppendLine("\tThe property IndParam.NumParam[" + param + "].ToolTip is not set.");
                    isOk = false;
                }
            }

            // Tests the IndParam.CheckParam properties.
            for (int param = 0; param < indicator.IndParam.CheckParam.Length; param++)
            {
                CheckParam checkParam = indicator.IndParam.CheckParam[param];
                if (!checkParam.Enabled)
                    continue;

                if (string.IsNullOrEmpty(checkParam.Caption))
                {
                    sb.AppendLine("\tThe property IndParam.CheckParam[" + param + "].Caption is not set.");
                    isOk = false;
                }

                if (string.IsNullOrEmpty(checkParam.ToolTip))
                {
                    sb.AppendLine("\tThe property IndParam.CheckParam[" + param + "].ToolTip is not set.");
                    isOk = false;
                }
            }

            try
            {
                indicator.Calculate(SlotTypes.NotDefined);
            }
            catch (Exception exc)
            {
                sb.AppendLine("\tError when executing Calculate(SlotTypes.NotDefined). " + exc.Message);
                isOk = false;
            }

            try
            {
                indicator.SetDescription(SlotTypes.NotDefined);
            }
            catch (Exception exc)
            {
                sb.AppendLine("\tError when executing SetDescription(SlotTypes.NotDefined). " + exc.Message);
                isOk = false;
            }

            try
            {
                indicator.ToString();
            }
            catch (Exception exc)
            {
                sb.AppendLine("\tError when executing ToString(). " + exc.Message);
                isOk = false;
            }

            errorList = isOk ? string.Empty : sb.ToString();

            return isOk;
        }
Пример #4
0
        /// <summary>
        /// Generates a HTML report about the opening logic.
        /// </summary>
        StringBuilder OpeningLogicHTMLReport()
        {
            var    sb            = new StringBuilder();
            string indicatorName = Data.Strategy.Slot[0].IndicatorName;

            Indicator indOpen = IndicatorStore.ConstructIndicator(indicatorName, SlotTypes.Open);

            indOpen.IndParam = Data.Strategy.Slot[0].IndParam;
            indOpen.SetDescription(SlotTypes.Open);

            // Logical groups of the opening conditions.
            var opengroups = new List <string>();

            for (int slot = 1; slot <= Data.Strategy.OpenFilters; slot++)
            {
                string group = Data.Strategy.Slot[slot].LogicalGroup;
                if (!opengroups.Contains(group) && group != "All")
                {
                    opengroups.Add(group); // Adds all groups except "All"
                }
            }
            if (opengroups.Count == 0 && Data.Strategy.OpenFilters > 0)
            {
                opengroups.Add("All"); // If all the slots are in "All" group, adds "All" to the list.
            }
            // Long position
            string openLong = "<p>";

            if (Data.Strategy.SameSignalAction == SameDirSignalAction.Add)
            {
                openLong = Language.T("Open a new long position or add to an existing position");
            }
            else if (Data.Strategy.SameSignalAction == SameDirSignalAction.Winner)
            {
                openLong = Language.T("Open a new long position or add to a winning position");
            }
            else if (Data.Strategy.SameSignalAction == SameDirSignalAction.Nothing)
            {
                openLong = Language.T("Open a new long position");
            }

            if (OppSignalAction == OppositeDirSignalAction.Close)
            {
                openLong += " " + Language.T("or close a short position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Reduce)
            {
                openLong += " " + Language.T("or reduce a short position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Reverse)
            {
                openLong += " " + Language.T("or reverse a short position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Nothing)
            {
                openLong += "";
            }

            openLong += " " + indOpen.EntryPointLongDescription;

            if (Data.Strategy.OpenFilters == 0)
            {
                openLong += ".</p>";
            }
            else if (Data.Strategy.OpenFilters == 1)
            {
                openLong += " " + Language.T("when the following logic condition is satisfied") + ":</p>";
            }
            else if (opengroups.Count > 1)
            {
                openLong += " " + Language.T("when") + ":</p>";
            }
            else
            {
                openLong += " " + Language.T("when all the following logic conditions are satisfied") + ":</p>";
            }

            sb.AppendLine(openLong);

            // Open Filters
            if (Data.Strategy.OpenFilters > 0)
            {
                int groupnumb = 1;
                if (opengroups.Count > 1)
                {
                    sb.AppendLine("<ul>");
                }

                foreach (string group in opengroups)
                {
                    if (opengroups.Count > 1)
                    {
                        sb.AppendLine("<li>" + (groupnumb == 1 ? "" : Language.T("or") + " ") + Language.T("logical group [#] is satisfied").Replace("#", group) + ":");
                        groupnumb++;
                    }

                    sb.AppendLine("<ul>");
                    int indInGroup = 0;
                    for (int slot = 1; slot <= Data.Strategy.OpenFilters; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup == group || Data.Strategy.Slot[slot].LogicalGroup == "All")
                        {
                            indInGroup++;
                        }
                    }

                    int indnumb = 1;
                    for (int slot = 1; slot <= Data.Strategy.OpenFilters; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup != group && Data.Strategy.Slot[slot].LogicalGroup != "All")
                        {
                            continue;
                        }

                        Indicator indOpenFilter = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, SlotTypes.OpenFilter);
                        indOpenFilter.IndParam = Data.Strategy.Slot[slot].IndParam;
                        indOpenFilter.SetDescription(SlotTypes.OpenFilter);

                        if (indnumb < indInGroup)
                        {
                            sb.AppendLine("<li>" + indOpenFilter.EntryFilterLongDescription + "; " + Language.T("and") + "</li>");
                        }
                        else
                        {
                            sb.AppendLine("<li>" + indOpenFilter.EntryFilterLongDescription + ".</li>");
                        }

                        indnumb++;
                    }
                    sb.AppendLine("</ul>");

                    if (opengroups.Count > 1)
                    {
                        sb.AppendLine("</li>");
                    }
                }

                if (opengroups.Count > 1)
                {
                    sb.AppendLine("</ul>");
                }
            }

            // Short position
            string openShort = "<p>";

            if (Data.Strategy.SameSignalAction == SameDirSignalAction.Add)
            {
                openShort = Language.T("Open a new short position or add to an existing position");
            }
            else if (Data.Strategy.SameSignalAction == SameDirSignalAction.Winner)
            {
                openShort = Language.T("Open a new short position or add to a winning position");
            }
            else if (Data.Strategy.SameSignalAction == SameDirSignalAction.Nothing)
            {
                openShort = Language.T("Open a new short position");
            }

            if (OppSignalAction == OppositeDirSignalAction.Close)
            {
                openShort += " " + Language.T("or close a long position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Reduce)
            {
                openShort += " " + Language.T("or reduce a long position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Reverse)
            {
                openShort += " " + Language.T("or reverse a long position");
            }
            else if (OppSignalAction == OppositeDirSignalAction.Nothing)
            {
                openShort += "";
            }

            openShort += " " + indOpen.EntryPointShortDescription;

            if (Data.Strategy.OpenFilters == 0)
            {
                openShort += ".</p>";
            }
            else if (Data.Strategy.OpenFilters == 1)
            {
                openShort += " " + Language.T("when the following logic condition is satisfied") + ":</p>";
            }
            else if (opengroups.Count > 1)
            {
                openShort += " " + Language.T("when") + ":</p>";
            }
            else
            {
                openShort += " " + Language.T("when all the following logic conditions are satisfied") + ":</p>";
            }

            sb.AppendLine(openShort);

            // Open Filters
            if (Data.Strategy.OpenFilters > 0)
            {
                int groupnumb = 1;
                if (opengroups.Count > 1)
                {
                    sb.AppendLine("<ul>");
                }

                foreach (string group in opengroups)
                {
                    if (opengroups.Count > 1)
                    {
                        sb.AppendLine("<li>" + (groupnumb == 1 ? "" : Language.T("or") + " ") + Language.T("logical group [#] is satisfied").Replace("#", group) + ":");
                        groupnumb++;
                    }

                    sb.AppendLine("<ul>");
                    int indInGroup = 0;
                    for (int slot = 1; slot <= Data.Strategy.OpenFilters; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup == group || Data.Strategy.Slot[slot].LogicalGroup == "All")
                        {
                            indInGroup++;
                        }
                    }

                    int indnumb = 1;
                    for (int slot = 1; slot <= Data.Strategy.OpenFilters; slot++)
                    {
                        if (Data.Strategy.Slot[slot].LogicalGroup != group && Data.Strategy.Slot[slot].LogicalGroup != "All")
                        {
                            continue;
                        }

                        Indicator indOpenFilter = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, SlotTypes.OpenFilter);
                        indOpenFilter.IndParam = Data.Strategy.Slot[slot].IndParam;
                        indOpenFilter.SetDescription(SlotTypes.OpenFilter);

                        if (indnumb < indInGroup)
                        {
                            sb.AppendLine("<li>" + indOpenFilter.EntryFilterShortDescription + "; " + Language.T("and") + "</li>");
                        }
                        else
                        {
                            sb.AppendLine("<li>" + indOpenFilter.EntryFilterShortDescription + ".</li>");
                        }

                        indnumb++;
                    }
                    sb.AppendLine("</ul>");

                    if (opengroups.Count > 1)
                    {
                        sb.AppendLine("</li>");
                    }
                }
                if (opengroups.Count > 1)
                {
                    sb.AppendLine("</ul>");
                }
            }

            return(sb);
        }