/// <summary>
        ///     Adds a new Open Filter to the strategy.
        /// </summary>
        /// <returns>The number of new Open Filter Slot.</returns>
        public int AddOpenFilter()
        {
            OpenFilters++;
            var aIndSlotOld = (IndicatorSlot[])Slot.Clone();

            Slot = new IndicatorSlot[Slots];
            int newSlotNumb = OpenFilters; // The number of new open filter slot.

            // Copy the open slot and all old open filters.
            for (int slot = 0; slot < newSlotNumb; slot++)
            {
                Slot[slot] = aIndSlotOld[slot];
            }

            // Copy the close slot and all close filters.
            for (int slot = newSlotNumb + 1; slot < Slots; slot++)
            {
                Slot[slot] = aIndSlotOld[slot - 1];
            }

            // Create the new slot.
            Slot[newSlotNumb] = new IndicatorSlot {
                SlotType = SlotTypes.OpenFilter
            };

            // Sets the slot numbers.
            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot].SlotNumber = slot;
            }

            return(newSlotNumb);
        }
Example #2
0
        /// <summary>
        ///  Returns a copy
        /// </summary>
        public IndicatorSlot Clone()
        {
            IndicatorSlot slot = new IndicatorSlot();

            slot.slotNumb         = slotNumb;
            slot.slotType         = slotType;
            slot.slotStatus       = slotStatus;
            slot.group            = group;
            slot.isDefined        = isDefined;
            slot.indicatorName    = indicatorName;
            slot.isSeparatedChart = isSeparatedChart;
            slot.minValue         = minValue;
            slot.maxValue         = maxValue;
            slot.indicatorParam   = indicatorParam.Clone();

            slot.adSpecValue = new double[adSpecValue.Length];
            adSpecValue.CopyTo(slot.adSpecValue, 0);

            slot.component = new IndicatorComp[component.Length];
            for (int i = 0; i < component.Length; i++)
            {
                slot.component[i] = component[i].Clone();
            }

            return(slot);
        }
        /// <summary>
        ///     Adds a new Close Filter to the strategy.
        /// </summary>
        /// <returns>The number of new Close Filter Slot.</returns>
        public int AddCloseFilter()
        {
            CloseFilters++;
            var aIndSlotOld = (IndicatorSlot[])Slot.Clone();

            Slot = new IndicatorSlot[Slots];
            int newSlotNumb = Slots - 1; // The number of new close filter slot.

            // Copy all old slots.
            for (int slot = 0; slot < newSlotNumb; slot++)
            {
                Slot[slot] = aIndSlotOld[slot];
            }

            // Create the new slot.
            Slot[newSlotNumb] = new IndicatorSlot {
                SlotType = SlotTypes.CloseFilter
            };

            // Sets the slot numbers.
            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot].SlotNumber = slot;
            }

            return(newSlotNumb);
        }
        /// <summary>
        ///     Returns a copy
        /// </summary>
        public IndicatorSlot Clone()
        {
            var slot = new IndicatorSlot
            {
                SlotNumber     = SlotNumber,
                SlotType       = SlotType,
                SlotStatus     = SlotStatus,
                LogicalGroup   = LogicalGroup,
                IsDefined      = IsDefined,
                IndicatorName  = IndicatorName,
                SeparatedChart = SeparatedChart,
                MinValue       = MinValue,
                MaxValue       = MaxValue,
                IndParam       = IndParam.Clone(),
                SpecValue      = new double[SpecValue.Length]
            };

            SpecValue.CopyTo(slot.SpecValue, 0);

            slot.Component = new IndicatorComp[Component.Length];
            for (int i = 0; i < Component.Length; i++)
            {
                slot.Component[i] = Component[i].Clone();
            }

            return(slot);
        }
        /// <summary>
        ///     Duplicates an logic condition.
        /// </summary>
        public void DuplicateFilter(int slotToDuplicate)
        {
            if (Slot[slotToDuplicate].SlotType == SlotTypes.OpenFilter && OpenFilters < MaxOpenFilters ||
                Slot[slotToDuplicate].SlotType == SlotTypes.CloseFilter && CloseFilters < MaxCloseFilters)
            {
                IndicatorSlot tempSlot = Slot[slotToDuplicate].Clone();

                if (Slot[slotToDuplicate].SlotType == SlotTypes.OpenFilter)
                {
                    int iAddedslot = AddOpenFilter();
                    Slot[iAddedslot] = tempSlot.Clone();
                }

                if (Slot[slotToDuplicate].SlotType == SlotTypes.CloseFilter)
                {
                    int addedslot = AddCloseFilter();
                    Slot[addedslot] = tempSlot.Clone();
                }

                // Sets the slot numbers.
                for (int slot = 0; slot < Slots; slot++)
                {
                    Slot[slot].SlotNumber = slot;
                }
            }
        }
        /// <summary>
        /// Prepare the strategy for generating
        /// </summary>
        private void PrepareStrategyForGenerating()
        {
            _lockedEntrySlot    = null;
            _lockedEntryFilters = 0;
            _aLockedEntryFilter = new IndicatorSlot[Math.Max(Strategy.MaxOpenFilters, _strategyBest.OpenFilters)];
            _lockedExitSlot     = null;
            _lockedExitFilters  = 0;
            _aLockedExitFilter  = new IndicatorSlot[Math.Max(Strategy.MaxCloseFilters, _strategyBest.CloseFilters)];

            // Copy the locked slots
            for (int slot = 0; slot < _strategyBest.Slots; slot++)
            {
                if (_strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Locked ||
                    _strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    if (_strategyBest.Slot[slot].SlotType == SlotTypes.Open)
                    {
                        _lockedEntrySlot = _strategyBest.Slot[slot];
                    }
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.OpenFilter)
                    {
                        _aLockedEntryFilter[_lockedEntryFilters] = _strategyBest.Slot[slot];
                        _lockedEntryFilters++;
                    }
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.Close)
                    {
                        _lockedExitSlot = _strategyBest.Slot[slot];
                    }
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.CloseFilter)
                    {
                        _aLockedExitFilter[_lockedExitFilters] = _strategyBest.Slot[slot];
                        _lockedExitFilters++;
                    }
                }
            }

            if (ChbGenerateNewStrategy.Checked)
            {
                _bestBalance = 0;
            }
            else
            {
                _bestBalance = (_isOOS ? Backtester.Balance(_barOOS) : Backtester.NetBalance);
            }

            _maxOpeningLogicSlots = ChbMaxOpeningLogicSlots.Checked
                                       ? (int)NUDMaxOpeningLogicSlots.Value
                                       : Strategy.MaxOpenFilters;
            _maxClosingLogicSlots = ChbMaxClosingLogicSlots.Checked
                                       ? (int)NUDMaxClosingLogicSlots.Value
                                       : Strategy.MaxCloseFilters;
        }
        /// <summary>
        ///     Removes all close filters from the strategy.
        /// </summary>
        public void RemoveAllCloseFilters()
        {
            CloseFilters = 0;
            var indSlotOld = (IndicatorSlot[])Slot.Clone();

            Slot = new IndicatorSlot[Slots];

            // Copy all slots except the close filters.
            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot] = indSlotOld[slot];
            }
        }
Example #8
0
        /// <summary>
        /// Prepare the strategy for generating
        /// </summary>
        void PrepareStrategyForGenerating()
        {
            lockedEntrySlot    = null;
            lockedEntryFilters = 0;
            aLockedEntryFilter = new IndicatorSlot[Math.Max(Strategy.MaxOpenFilters, strategyBest.OpenFilters)];
            lockedExitSlot     = null;
            lockedExitFilters  = 0;
            aLockedExitFilter  = new IndicatorSlot[Math.Max(Strategy.MaxCloseFilters, strategyBest.CloseFilters)];

            // Copy the locked slots
            for (int slot = 0; slot < strategyBest.Slots; slot++)
            {
                if (strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Locked ||
                    strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    if (strategyBest.Slot[slot].SlotType == SlotTypes.Open)
                    {
                        lockedEntrySlot = strategyBest.Slot[slot];
                    }
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.OpenFilter)
                    {
                        aLockedEntryFilter[lockedEntryFilters] = strategyBest.Slot[slot];
                        lockedEntryFilters++;
                    }
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.Close)
                    {
                        lockedExitSlot = strategyBest.Slot[slot];
                    }
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.CloseFilter)
                    {
                        aLockedExitFilter[lockedExitFilters] = strategyBest.Slot[slot];
                        lockedExitFilters++;
                    }
                }
            }

            if (chbGenerateNewStrategy.Checked)
            {
                bestBalance = 0;
            }
            else
            {
                bestBalance = (isOOS ? Backtester.Balance(barOOS) : Backtester.NetBalance);
            }

            maxOpeningLogicSlots = chbMaxOpeningLogicSlots.Checked ? (int)nudMaxOpeningLogicSlots.Value: Strategy.MaxOpenFilters;
            maxClosingLogicSlots = chbMaxClosingLogicSlots.Checked ? (int)nudMaxClosingLogicSlots.Value: Strategy.MaxCloseFilters;

            return;
        }
        /// <summary>
        ///     Creates a strategy
        /// </summary>
        private void CreateStrategy(int openFilters, int closeFilters)
        {
            StrategyName = "Unnamed";
            OpenFilters  = openFilters;
            CloseFilters = closeFilters;
            Slot         = new IndicatorSlot[Slots];

            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot] = new IndicatorSlot {
                    SlotNumber = slot, SlotType = GetSlotType(slot)
                };
            }
        }
        /// <summary>
        ///     Moves a filter downwards.
        /// </summary>
        public void MoveFilterDownwards(int slotToMove)
        {
            if (slotToMove >= Slots - 1 || Slot[slotToMove].SlotType != Slot[slotToMove + 1].SlotType)
            {
                return;
            }
            IndicatorSlot tempSlot = Slot[slotToMove + 1].Clone();

            Slot[slotToMove + 1] = Slot[slotToMove].Clone();
            Slot[slotToMove]     = tempSlot.Clone();

            // Sets the slot numbers.
            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot].SlotNumber = slot;
            }
        }
        /// <summary>
        /// Shows if the slot has any parameters to generate.
        /// </summary>
        private bool IsSlotHasParameters(IndicatorSlot slot)
        {
            foreach (ListParam listParam in slot.IndParam.ListParam)
            {
                if (listParam.Enabled && listParam.ItemList.Length > 1)
                {
                    return(true);
                }
            }
            foreach (NumericParam numericParam in slot.IndParam.NumParam)
            {
                if (numericParam.Enabled)
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        ///     Removes a filter from the strategy.
        /// </summary>
        public void RemoveFilter(int slotToRemove)
        {
            if (Slot[slotToRemove].SlotType != SlotTypes.OpenFilter &&
                Slot[slotToRemove].SlotType != SlotTypes.CloseFilter)
            {
                return;
            }

            if (slotToRemove < CloseSlot)
            {
                OpenFilters--;
            }
            else
            {
                CloseFilters--;
            }
            var indSlotOld = (IndicatorSlot[])Slot.Clone();

            Slot = new IndicatorSlot[Slots];

            // Copy all filters before this that has to be removed.
            for (int slot = 0; slot < slotToRemove; slot++)
            {
                Slot[slot] = indSlotOld[slot];
            }

            // Copy all filters after this that has to be removed.
            for (int slot = slotToRemove; slot < Slots; slot++)
            {
                Slot[slot] = indSlotOld[slot + 1];
            }

            // Sets the slot numbers.
            for (int slot = 0; slot < Slots; slot++)
            {
                Slot[slot].SlotNumber = slot;
            }
        }
Example #13
0
        /// <summary>
        ///     Represents the Strategy as a XmlDocument.
        /// </summary>
        public static XmlDocument CreateStrategyXmlDoc(Strategy strategy)
        {
            // Create the XmlDocument.
            var xmlDocStrategy = new XmlDocument();

            xmlDocStrategy.LoadXml("<strategy></strategy>");

            //Create the XML declaration.
            XmlDeclaration xmldecl = xmlDocStrategy.CreateXmlDeclaration("1.0", null, null);

            //Add new node to the document.
            XmlElement root = xmlDocStrategy.DocumentElement;

            xmlDocStrategy.InsertBefore(xmldecl, root);

            AppendStringElement(xmlDocStrategy, "programName", Data.ProgramName);
            AppendStringElement(xmlDocStrategy, "programVersion", Data.ProgramVersion);
            AppendStringElement(xmlDocStrategy, "strategyName", strategy.StrategyName);
            AppendStringElement(xmlDocStrategy, "instrumentSymbol", strategy.Symbol);
            AppendStringElement(xmlDocStrategy, "instrumentPeriod", (int)strategy.DataPeriod);
            AppendStringElement(xmlDocStrategy, "sameDirSignalAction", strategy.SameSignalAction.ToString());
            AppendStringElement(xmlDocStrategy, "oppDirSignalAction", strategy.OppSignalAction.ToString());

            // Add the Permanent Stop Loss
            XmlElement newElem = xmlDocStrategy.CreateElement("permanentStopLoss");

            newElem.InnerText = strategy.PermanentSL.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("usePermanentSL", strategy.UsePermanentSL.ToString(CultureInfo.InvariantCulture));
            newElem.SetAttribute("permanentSLType", strategy.PermanentSLType.ToString());
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            // Add the Permanent Take Profit
            newElem           = xmlDocStrategy.CreateElement("permanentTakeProfit");
            newElem.InnerText = strategy.PermanentTP.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("usePermanentTP", strategy.UsePermanentTP.ToString(CultureInfo.InvariantCulture));
            newElem.SetAttribute("permanentTPType", strategy.PermanentTPType.ToString());
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            // Add the Break Even
            newElem           = xmlDocStrategy.CreateElement("breakEven");
            newElem.InnerText = strategy.BreakEven.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("useBreakEven", strategy.UseBreakEven.ToString(CultureInfo.InvariantCulture));
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            AppendStringElement(xmlDocStrategy, "maxOpenLots", strategy.MaxOpenLots);
            AppendStringElement(xmlDocStrategy, "useAccountPercentEntry", strategy.UseAccountPercentEntry);
            AppendStringElement(xmlDocStrategy, "entryLots", strategy.EntryLots);
            AppendStringElement(xmlDocStrategy, "addingLots", strategy.AddingLots);
            AppendStringElement(xmlDocStrategy, "reducingLots", strategy.ReducingLots);
            AppendStringElement(xmlDocStrategy, "useMartingale", strategy.UseMartingale);
            AppendStringElement(xmlDocStrategy, "martingaleMultiplier", strategy.MartingaleMultiplier);
            AppendStringElement(xmlDocStrategy, "description", strategy.Description);

            // Add the slots.
            AppendStringElement(xmlDocStrategy, "openFilters", strategy.OpenFilters);
            AppendStringElement(xmlDocStrategy, "closeFilters", strategy.CloseFilters);
            for (int slot = 0; slot < strategy.Slots; slot++)
            {
                IndicatorSlot stratSlot = strategy.Slot[slot];
                SlotTypes     slType    = stratSlot.SlotType;

                // Add a slot element.
                XmlElement newSlot = xmlDocStrategy.CreateElement("slot");
                newSlot.SetAttribute("slotNumber", slot.ToString(CultureInfo.InvariantCulture));
                newSlot.SetAttribute("slotType", slType.ToString());

                if (slType == SlotTypes.OpenFilter || slType == SlotTypes.CloseFilter)
                {
                    newSlot.SetAttribute("logicalGroup", stratSlot.LogicalGroup);
                }

                // Add an element.
                newElem           = xmlDocStrategy.CreateElement("indicatorName");
                newElem.InnerText = stratSlot.IndicatorName;
                newSlot.AppendChild(newElem);

                // Add the list parameters.
                for (int param = 0; param < stratSlot.IndParam.ListParam.Length; param++)
                {
                    if (!stratSlot.IndParam.ListParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newListElem = xmlDocStrategy.CreateElement("listParam");
                    newListElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Caption;
                    newListElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("index");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Index.ToString(CultureInfo.InvariantCulture);
                    newListElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Text;
                    newListElem.AppendChild(newElem);

                    newSlot.AppendChild(newListElem);
                }

                // Add the num parameters.
                for (int param = 0; param < stratSlot.IndParam.NumParam.Length; param++)
                {
                    if (!stratSlot.IndParam.NumParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newNumElem = xmlDocStrategy.CreateElement("numParam");
                    newNumElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.NumParam[param].Caption;
                    newNumElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText = stratSlot.IndParam.NumParam[param].ValueToString;
                    newNumElem.AppendChild(newElem);

                    newSlot.AppendChild(newNumElem);
                }

                // Add the check parameters.
                for (int param = 0; param < stratSlot.IndParam.CheckParam.Length; param++)
                {
                    if (!stratSlot.IndParam.CheckParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newCheckElem = xmlDocStrategy.CreateElement("checkParam");
                    newCheckElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.CheckParam[param].Caption;
                    newCheckElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText =
                        stratSlot.IndParam.CheckParam[param].Checked.ToString(CultureInfo.InvariantCulture);
                    newCheckElem.AppendChild(newElem);

                    newSlot.AppendChild(newCheckElem);
                }

                if (xmlDocStrategy.DocumentElement != null)
                {
                    xmlDocStrategy.DocumentElement.AppendChild(newSlot);
                }
            }

            return(xmlDocStrategy);
        }
        /// <summary>
        ///  Returns a copy
        /// </summary>
        public IndicatorSlot Clone()
        {
            IndicatorSlot slot = new IndicatorSlot();
            slot.slotNumb         = slotNumb;
            slot.slotType         = slotType;
            slot.slotStatus       = slotStatus;
            slot.group            = group;
            slot.isDefined        = isDefined;
            slot.indicatorName    = indicatorName;
            slot.isSeparatedChart = isSeparatedChart;
            slot.minValue         = minValue;
            slot.maxValue         = maxValue;
            slot.indicatorParam   = indicatorParam.Clone();

            slot.adSpecValue = new double[adSpecValue.Length];
            adSpecValue.CopyTo(slot.adSpecValue, 0);

            slot.component = new IndicatorComp[component.Length];
            for (int i = 0; i < component.Length; i++)
                slot.component[i] = component[i].Clone();

            return slot;
        }
Example #15
0
        /// <summary>
        /// Normalizes the numeric parameters.
        /// </summary>
        void ReduceTheValuesOfNumericParams(BackgroundWorker worker)
        {
            bool isDoAgain;

            for (int slot = 0; slot < Data.Strategy.Slots; slot++)
            {
                if (bestBalance < 500)
                {
                    break;
                }
                if (Data.Strategy.Slot[slot].SlotStatus == StrategySlotStatus.Locked)
                {
                    continue;
                }

                // Numeric parameters
                for (int param = 0; param < 6; param++)
                {
                    if (!Data.Strategy.Slot[slot].IndParam.NumParam[param].Enabled)
                    {
                        continue;
                    }

                    do
                    {
                        if (worker.CancellationPending)
                        {
                            break;
                        }
                        isDoAgain = false;

                        IndicatorSlot indSlot = Data.Strategy.Slot[slot];
                        NumericParam  num     = Data.Strategy.Slot[slot].IndParam.NumParam[param];
                        if (num.Caption == "Level" && !indSlot.IndParam.ListParam[0].Text.Contains("Level"))
                        {
                            break;
                        }

                        Indicator indicator    = Indicator_Store.ConstructIndicator(indSlot.IndicatorName, indSlot.SlotType);
                        double    defaultValue = indicator.IndParam.NumParam[param].Value;

                        double numOldValue = num.Value;
                        if (num.Value == defaultValue)
                        {
                            break;
                        }

                        double step  = Math.Pow(10, -num.Point);
                        double value = num.Value;
                        double delta = (defaultValue - value) * 3 / 4;
                        value += delta;
                        value  = Math.Round(value, num.Point);

                        if (Math.Abs(value - numOldValue) < value)
                        {
                            break;
                        }

                        num.Value = value;

                        RecalculateSlots();
                        isDoAgain = CalculateTheResult(true);
                        if (!isDoAgain)
                        {
                            RestoreFromBest();
                        }
                    } while (isDoAgain);
                }
            }
        }
        /// <summary>
        /// Prepare the strategy for generating
        /// </summary>
        private void PrepareStrategyForGenerating()
        {
            _lockedEntrySlot = null;
            _lockedEntryFilters = 0;
            _aLockedEntryFilter = new IndicatorSlot[Math.Max(Strategy.MaxOpenFilters, _strategyBest.OpenFilters)];
            _lockedExitSlot = null;
            _lockedExitFilters = 0;
            _aLockedExitFilter = new IndicatorSlot[Math.Max(Strategy.MaxCloseFilters, _strategyBest.CloseFilters)];

            // Copy the locked slots
            for (int slot = 0; slot < _strategyBest.Slots; slot++)
            {
                if (_strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Locked ||
                    _strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    if (_strategyBest.Slot[slot].SlotType == SlotTypes.Open)
                        _lockedEntrySlot = _strategyBest.Slot[slot];
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.OpenFilter)
                    {
                        _aLockedEntryFilter[_lockedEntryFilters] = _strategyBest.Slot[slot];
                        _lockedEntryFilters++;
                    }
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.Close)
                        _lockedExitSlot = _strategyBest.Slot[slot];
                    else if (_strategyBest.Slot[slot].SlotType == SlotTypes.CloseFilter)
                    {
                        _aLockedExitFilter[_lockedExitFilters] = _strategyBest.Slot[slot];
                        _lockedExitFilters++;
                    }
                }
            }

            if (ChbGenerateNewStrategy.Checked)
                _bestBalance = 0;
            else
                _bestBalance = (_isOOS ? Backtester.Balance(_barOOS) : Backtester.NetBalance);

            _maxOpeningLogicSlots = ChbMaxOpeningLogicSlots.Checked
                                       ? (int) NUDMaxOpeningLogicSlots.Value
                                       : Strategy.MaxOpenFilters;
            _maxClosingLogicSlots = ChbMaxClosingLogicSlots.Checked
                                       ? (int) NUDMaxClosingLogicSlots.Value
                                       : Strategy.MaxCloseFilters;
        }
        /// <summary>
        ///  Returns a copy
        /// </summary>
        public IndicatorSlot Clone()
        {
            var slot = new IndicatorSlot
                           {
                               SlotNumber = SlotNumber,
                               SlotType = SlotType,
                               SlotStatus = SlotStatus,
                               LogicalGroup = LogicalGroup,
                               IsDefined = IsDefined,
                               IndicatorName = IndicatorName,
                               SeparatedChart = SeparatedChart,
                               MinValue = MinValue,
                               MaxValue = MaxValue,
                               IndParam = IndParam.Clone(),
                               SpecValue = new double[SpecValue.Length]
                           };

            SpecValue.CopyTo(slot.SpecValue, 0);

            slot.Component = new IndicatorComp[Component.Length];
            for (int i = 0; i < Component.Length; i++)
                slot.Component[i] = Component[i].Clone();

            return slot;
        }
Example #18
0
        /// <summary>
        ///     Pareses a strategy from a xml document.
        /// </summary>
        public Strategy ParseXmlStrategy(XmlDocument xmlDocStrategy)
        {
            // Read the number of slots
            int openFilters  = int.Parse(xmlDocStrategy.GetElementsByTagName("openFilters")[0].InnerText);
            int closeFilters = int.Parse(xmlDocStrategy.GetElementsByTagName("closeFilters")[0].InnerText);

            // Create the strategy.
            // ReSharper disable UseObjectOrCollectionInitializer
            var tempStrategy = new Strategy(openFilters, closeFilters);

            // ReSharper restore UseObjectOrCollectionInitializer

            // Same and Opposite direction Actions
            tempStrategy.SameSignalAction =
                (SameDirSignalAction)
                Enum.Parse(typeof(SameDirSignalAction),
                           xmlDocStrategy.GetElementsByTagName("sameDirSignalAction")[0].InnerText);
            tempStrategy.OppSignalAction =
                (OppositeDirSignalAction)
                Enum.Parse(typeof(OppositeDirSignalAction),
                           xmlDocStrategy.GetElementsByTagName("oppDirSignalAction")[0].InnerText);

            // Market
            tempStrategy.Symbol = xmlDocStrategy.GetElementsByTagName("instrumentSymbol")[0].InnerText;
            string period = xmlDocStrategy.GetElementsByTagName("instrumentPeriod")[0].InnerText;

            tempStrategy.DataPeriod = ImportDataPeriod(period);

            // Permanent Stop Loss
            tempStrategy.PermanentSL =
                Math.Abs(int.Parse(xmlDocStrategy.GetElementsByTagName("permanentStopLoss")[0].InnerText));
            // Math.Abs() removes the negative sign from previous versions.
            XmlAttributeCollection xmlAttributeCollection =
                xmlDocStrategy.GetElementsByTagName("permanentStopLoss")[0].Attributes;

            if (xmlAttributeCollection != null)
            {
                tempStrategy.UsePermanentSL = bool.Parse(xmlAttributeCollection["usePermanentSL"].InnerText);
                try
                {
                    tempStrategy.PermanentSLType =
                        (PermanentProtectionType)
                        Enum.Parse(typeof(PermanentProtectionType), xmlAttributeCollection["permanentSLType"].InnerText);
                }
                catch
                {
                    tempStrategy.PermanentSLType = PermanentProtectionType.Relative;
                }
            }

            // Permanent Take Profit
            tempStrategy.PermanentTP = int.Parse(xmlDocStrategy.GetElementsByTagName("permanentTakeProfit")[0].InnerText);
            XmlAttributeCollection attributeCollection =
                xmlDocStrategy.GetElementsByTagName("permanentTakeProfit")[0].Attributes;

            if (attributeCollection != null)
            {
                tempStrategy.UsePermanentTP = bool.Parse(attributeCollection["usePermanentTP"].InnerText);
                try
                {
                    tempStrategy.PermanentTPType =
                        (PermanentProtectionType)
                        Enum.Parse(typeof(PermanentProtectionType), attributeCollection["permanentTPType"].InnerText);
                }
                catch
                {
                    tempStrategy.PermanentTPType = PermanentProtectionType.Relative;
                }
            }

            // Break Even
            try
            {
                tempStrategy.BreakEven = int.Parse(xmlDocStrategy.GetElementsByTagName("breakEven")[0].InnerText);
                XmlAttributeCollection attributes = xmlDocStrategy.GetElementsByTagName("breakEven")[0].Attributes;
                if (attributes != null)
                {
                    tempStrategy.UseBreakEven = bool.Parse(attributes["useBreakEven"].InnerText);
                }
            }
            catch (Exception exception)
            {
                Console.Write(exception.Message);
            }

            // Money Management
            try
            {
                tempStrategy.UseAccountPercentEntry =
                    bool.Parse(xmlDocStrategy.GetElementsByTagName("useAccountPercentEntry")[0].InnerText);
            }
            catch
            {
                tempStrategy.UseAccountPercentEntry =
                    bool.Parse(xmlDocStrategy.GetElementsByTagName("useAcountPercentEntry")[0].InnerText);
            }
            tempStrategy.MaxOpenLots  = StringToDouble(xmlDocStrategy.GetElementsByTagName("maxOpenLots")[0].InnerText);
            tempStrategy.EntryLots    = StringToDouble(xmlDocStrategy.GetElementsByTagName("entryLots")[0].InnerText);
            tempStrategy.AddingLots   = StringToDouble(xmlDocStrategy.GetElementsByTagName("addingLots")[0].InnerText);
            tempStrategy.ReducingLots = StringToDouble(xmlDocStrategy.GetElementsByTagName("reducingLots")[0].InnerText);
            try
            {
                tempStrategy.UseMartingale =
                    bool.Parse(xmlDocStrategy.GetElementsByTagName("useMartingale")[0].InnerText);
                tempStrategy.MartingaleMultiplier =
                    StringToDouble(xmlDocStrategy.GetElementsByTagName("martingaleMultiplier")[0].InnerText);
            }
            catch
            {
                tempStrategy.UseMartingale        = false;
                tempStrategy.MartingaleMultiplier = 2.0;
            }

            // Description
            tempStrategy.Description = xmlDocStrategy.GetElementsByTagName("description")[0].InnerText;

            // Strategy name.
            tempStrategy.StrategyName = xmlDocStrategy.GetElementsByTagName("strategyName")[0].InnerText;

            // Reading the slots
            XmlNodeList xmlSlotList = xmlDocStrategy.GetElementsByTagName("slot");

            for (int slot = 0; slot < xmlSlotList.Count; slot++)
            {
                XmlNodeList   xmlSlotTagList = xmlSlotList[slot].ChildNodes;
                IndicatorSlot tempSlot       = tempStrategy.Slot[slot];

                XmlAttributeCollection collection = xmlSlotList[slot].Attributes;
                if (collection != null)
                {
                    // Identify the Slot Type
                    var slotType = (SlotTypes)Enum.Parse(typeof(SlotTypes), collection["slotType"].InnerText);

                    // Logical group
                    if (slotType == SlotTypes.OpenFilter || slotType == SlotTypes.CloseFilter)
                    {
                        XmlAttributeCollection attributes = collection;
                        XmlNode nodeGroup = attributes.GetNamedItem("logicalGroup");
                        string  defGroup  = GetDefaultGroup(slotType, slot, tempStrategy.CloseSlot);
                        if (nodeGroup != null)
                        {
                            string group = nodeGroup.InnerText;
                            tempSlot.LogicalGroup = @group;
                            if (@group != defGroup && @group.ToLower() != "all" && !Configs.UseLogicalGroups)
                            {
                                MessageBox.Show(
                                    Language.T("The strategy requires logical groups.") + Environment.NewLine +
                                    Language.T("\"Use Logical Groups\" option was temporarily switched on."),
                                    Language.T("Logical Groups"),
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);
                                Configs.UseLogicalGroups = true;
                            }
                        }
                        else
                        {
                            tempSlot.LogicalGroup = defGroup;
                        }
                    }

                    // Indicator name.
                    string indicatorName = xmlSlotTagList[0].InnerText;
                    if (!IndicatorManager.AllIndicatorsNames.Contains(indicatorName))
                    {
                        string message = string.Format("Indicator \"{0}\" was not found.", indicatorName);
                        throw new MissingIndicatorException(message);
                    }

                    Indicator indicator = IndicatorManager.ConstructIndicator(indicatorName);
                    indicator.Initialize(slotType);

                    for (int tag = 1; tag < xmlSlotTagList.Count; tag++)
                    {
                        // List parameters
                        if (xmlSlotTagList[tag].Name == "listParam")
                        {
                            XmlAttributeCollection attributes = xmlSlotTagList[tag].Attributes;
                            if (attributes != null)
                            {
                                int     listParam        = int.Parse(attributes["paramNumber"].InnerText);
                                XmlNode xmlListParamNode = xmlSlotTagList[tag].FirstChild;

                                indicator.IndParam.ListParam[listParam].Caption = xmlListParamNode.InnerText;

                                xmlListParamNode = xmlListParamNode.NextSibling;
                                if (xmlListParamNode != null)
                                {
                                    int index = int.Parse(xmlListParamNode.InnerText);
                                    indicator.IndParam.ListParam[listParam].Index = index;
                                    indicator.IndParam.ListParam[listParam].Text  =
                                        indicator.IndParam.ListParam[listParam].ItemList[index];
                                }
                            }
                        }

                        // Numeric parameters
                        if (xmlSlotTagList[tag].Name == "numParam")
                        {
                            XmlNode xmlNumParamNode           = xmlSlotTagList[tag].FirstChild;
                            XmlAttributeCollection attributes = xmlSlotTagList[tag].Attributes;
                            if (attributes != null)
                            {
                                int numParam = int.Parse(attributes["paramNumber"].InnerText);
                                indicator.IndParam.NumParam[numParam].Caption = xmlNumParamNode.InnerText;

                                xmlNumParamNode = xmlNumParamNode.NextSibling;
                                if (xmlNumParamNode != null)
                                {
                                    string numParamValue = xmlNumParamNode.InnerText;
                                    numParamValue = numParamValue.Replace(',', Data.PointChar);
                                    numParamValue = numParamValue.Replace('.', Data.PointChar);
                                    float value = float.Parse(numParamValue);

                                    // Removing of the Stop Loss negative sign used in previous versions.
                                    string parCaption = indicator.IndParam.NumParam[numParam].Caption;
                                    if (parCaption == "Trailing Stop" ||
                                        parCaption == "Initial Stop Loss" ||
                                        parCaption == "Stop Loss")
                                    {
                                        value = Math.Abs(value);
                                    }
                                    indicator.IndParam.NumParam[numParam].Value = value;
                                }
                            }
                        }

                        // Check parameters
                        if (xmlSlotTagList[tag].Name == "checkParam")
                        {
                            XmlNode xmlCheckParamNode         = xmlSlotTagList[tag].FirstChild;
                            XmlAttributeCollection attributes = xmlSlotTagList[tag].Attributes;
                            if (attributes != null)
                            {
                                int checkParam = int.Parse(attributes["paramNumber"].InnerText);
                                indicator.IndParam.CheckParam[checkParam].Caption = xmlCheckParamNode.InnerText;

                                xmlCheckParamNode = xmlCheckParamNode.NextSibling;
                                if (xmlCheckParamNode != null)
                                {
                                    indicator.IndParam.CheckParam[checkParam].Checked =
                                        bool.Parse(xmlCheckParamNode.InnerText);
                                }
                            }
                        }
                    }

                    if (slotType == SlotTypes.OpenFilter || slotType == SlotTypes.CloseFilter)
                    {
                        // Signal shift type.
                        XmlNodeList signalShiftType = xmlSlotList[slot].SelectNodes("signalShiftType");
                        tempSlot.SignalShiftType = signalShiftType.Count == 0
                                                       ? SignalShiftType.At
                                                       : (SignalShiftType)
                                                   Enum.Parse(typeof(SignalShiftType),
                                                              signalShiftType[0].InnerText);

                        // Signal shift type.
                        XmlNodeList signalShift = xmlSlotList[slot].SelectNodes("signalShift");
                        tempSlot.SignalShift = signalShift.Count == 0
                                                   ? 0
                                                   : int.Parse(signalShift[0].InnerText);

                        // Symbol
                        XmlNodeList indicatorSymbol = xmlSlotList[slot].SelectNodes("indicatorSymbol");
                        tempSlot.IndicatorSymbol = indicatorSymbol.Count == 0
                                                       ? string.Empty
                                                       : indicatorSymbol[0].InnerText;

                        // Period
                        XmlNodeList indicatorPeriod = xmlSlotList[slot].SelectNodes("indicatorPeriod");
                        tempSlot.IndicatorPeriod = indicatorPeriod.Count == 0
                                                       ? DataPeriod.M1
                                                       : ImportDataPeriod(indicatorPeriod[0].InnerText);
                    }

                    // Calculate the indicator.
                    indicator.Calculate(Data.DataSet);
                    tempSlot.IndicatorName  = indicator.IndicatorName;
                    tempSlot.IndParam       = indicator.IndParam;
                    tempSlot.Component      = indicator.Component;
                    tempSlot.SeparatedChart = indicator.SeparatedChart;
                    tempSlot.SpecValue      = indicator.SpecialValues;
                    tempSlot.MinValue       = indicator.SeparatedChartMinValue;
                    tempSlot.MaxValue       = indicator.SeparatedChartMaxValue;
                }
                tempSlot.IsDefined = true;
            }

            return(tempStrategy);
        }
        /// <summary>
        /// Prepare the strategy for generating
        /// </summary>
        void PrepareStrategyForGenerating()
        {
            lockedEntrySlot    = null;
            lockedEntryFilters = 0;
            aLockedEntryFilter = new IndicatorSlot[Math.Max(Strategy.MaxOpenFilters, strategyBest.OpenFilters)];
            lockedExitSlot     = null;
            lockedExitFilters  = 0;
            aLockedExitFilter  = new IndicatorSlot[Math.Max(Strategy.MaxCloseFilters, strategyBest.CloseFilters)];

            // Copy the locked slots
            for (int slot = 0; slot < strategyBest.Slots; slot++)
            {
                if (strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Locked ||
                    strategyBest.Slot[slot].SlotStatus == StrategySlotStatus.Linked)
                {
                    if (strategyBest.Slot[slot].SlotType == SlotTypes.Open)
                        lockedEntrySlot = strategyBest.Slot[slot];
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.OpenFilter)
                    {
                        aLockedEntryFilter[lockedEntryFilters] = strategyBest.Slot[slot];
                        lockedEntryFilters++;
                    }
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.Close)
                        lockedExitSlot = strategyBest.Slot[slot];
                    else if (strategyBest.Slot[slot].SlotType == SlotTypes.CloseFilter)
                    {
                        aLockedExitFilter[lockedExitFilters] = strategyBest.Slot[slot];
                        lockedExitFilters++;
                    }
                }
            }

            if (chbGenerateNewStrategy.Checked)
                bestBalance = 0;
            else
                bestBalance = (isOOS ? Backtester.Balance(barOOS) : Backtester.NetBalance);

            maxOpeningLogicSlots = chbMaxOpeningLogicSlots.Checked ? (int)nudMaxOpeningLogicSlots.Value: Strategy.MaxOpenFilters;
            maxClosingLogicSlots = chbMaxClosingLogicSlots.Checked ? (int)nudMaxClosingLogicSlots.Value: Strategy.MaxCloseFilters;

            return;
        }
        /// <summary>
        /// Calculate the indicator in the designated slot
        /// </summary>
        private void GenerateIndicatorParameters(int slot)
        {
            string    indicatorName = Data.Strategy.Slot[slot].IndicatorName;
            SlotTypes slotType      = Data.Strategy.GetSlotType(slot);
            Indicator indicator     = IndicatorStore.ConstructIndicator(indicatorName, slotType);

            // List parameters
            foreach (ListParam list in indicator.IndParam.ListParam)
            {
                if (list.Enabled)
                {
                    do
                    {
                        list.Index = _random.Next(list.ItemList.Length);
                        list.Text  = list.ItemList[list.Index];
                    } while (list.Caption == "Base price" && (list.Text == "High" || list.Text == "Low"));
                }
            }

            int firstBar;

            do
            {
                // Numeric parameters
                foreach (NumericParam num in indicator.IndParam.NumParam)
                {
                    if (num.Enabled)
                    {
                        if (num.Caption == "Level" && !indicator.IndParam.ListParam[0].Text.Contains("Level"))
                        {
                            continue;
                        }
                        if (!ChbUseDefaultIndicatorValues.Checked)
                        {
                            double step    = Math.Pow(10, -num.Point);
                            double minimum = num.Min;
                            double maximum = num.Max;

                            if (maximum > Data.Bars / 3.0 && ((num.Caption.ToLower()).Contains("period") ||
                                                              (num.Caption.ToLower()).Contains("shift") ||
                                                              (num.ToolTip.ToLower()).Contains("period")))
                            {
                                maximum = Math.Max(minimum + step, Data.Bars / 3.0);
                            }

                            double value = minimum + step * _random.Next((int)((maximum - minimum) / step));
                            num.Value = Math.Round(value, num.Point);
                        }
                    }
                }

                if (!CalculateIndicator(slotType, indicator))
                {
                    return;
                }

                firstBar = 0;
                foreach (IndicatorComp comp in indicator.Component)
                {
                    if (comp.FirstBar > firstBar)
                    {
                        firstBar = comp.FirstBar;
                    }
                }
            } while (firstBar > Data.Bars - 10);

            //Set the Data.Strategy
            IndicatorSlot indSlot = Data.Strategy.Slot[slot];

            indSlot.IndicatorName  = indicator.IndicatorName;
            indSlot.IndParam       = indicator.IndParam;
            indSlot.Component      = indicator.Component;
            indSlot.SeparatedChart = indicator.SeparatedChart;
            indSlot.SpecValue      = indicator.SpecialValues;
            indSlot.MinValue       = indicator.SeparatedChartMinValue;
            indSlot.MaxValue       = indicator.SeparatedChartMaxValue;
            indSlot.IsDefined      = true;
        }
        /// <summary>
        /// Shows if the slot has any parameters to generate.
        /// </summary>
        private bool IsSlotHasParameters(IndicatorSlot slot)
        {
            foreach (ListParam listParam in slot.IndParam.ListParam)
                if (listParam.Enabled && listParam.ItemList.Length > 1)
                    return true;
            foreach (NumericParam numericParam in slot.IndParam.NumParam)
                if (numericParam.Enabled)
                    return true;

            return false;
        }
        /// <summary>
        ///     Represents the Strategy as a XmlDocument.
        /// </summary>
        public static XmlDocument CreateStrategyXmlDoc(Strategy strategy)
        {
            // Create the XmlDocument.
            var xmlDocStrategy = new XmlDocument();

            xmlDocStrategy.LoadXml("<strategy></strategy>");

            //Create the XML declaration.
            XmlDeclaration xmldecl = xmlDocStrategy.CreateXmlDeclaration("1.0", null, null);

            //Add new node to the document.
            XmlElement root = xmlDocStrategy.DocumentElement;

            xmlDocStrategy.InsertBefore(xmldecl, root);

            AppendStringElement(xmlDocStrategy, "programName", Data.ProgramName);
            AppendStringElement(xmlDocStrategy, "programVersion", Data.ProgramVersion);
            AppendStringElement(xmlDocStrategy, "strategyName", strategy.StrategyName);
            AppendStringElement(xmlDocStrategy, "instrumentSymbol", strategy.Symbol);
            AppendStringElement(xmlDocStrategy, "instrumentPeriod", (int)strategy.DataPeriod);
            AppendStringElement(xmlDocStrategy, "sameDirSignalAction", strategy.SameSignalAction.ToString());
            AppendStringElement(xmlDocStrategy, "oppDirSignalAction", strategy.OppSignalAction.ToString());

            // Add the Permanent Stop Loss
            XmlElement newElem = xmlDocStrategy.CreateElement("permanentStopLoss");

            newElem.InnerText = strategy.PermanentSL.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("usePermanentSL", strategy.UsePermanentSL.ToString(CultureInfo.InvariantCulture));
            newElem.SetAttribute("permanentSLType", strategy.PermanentSLType.ToString());
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            // Add the Permanent Take Profit
            newElem           = xmlDocStrategy.CreateElement("permanentTakeProfit");
            newElem.InnerText = strategy.PermanentTP.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("usePermanentTP", strategy.UsePermanentTP.ToString(CultureInfo.InvariantCulture));
            newElem.SetAttribute("permanentTPType", strategy.PermanentTPType.ToString());
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            // Add the Break Even
            newElem           = xmlDocStrategy.CreateElement("breakEven");
            newElem.InnerText = strategy.BreakEven.ToString(CultureInfo.InvariantCulture);
            newElem.SetAttribute("useBreakEven", strategy.UseBreakEven.ToString(CultureInfo.InvariantCulture));
            if (xmlDocStrategy.DocumentElement != null)
            {
                xmlDocStrategy.DocumentElement.AppendChild(newElem);
            }

            AppendStringElement(xmlDocStrategy, "maxOpenLots", strategy.MaxOpenLots);
            AppendStringElement(xmlDocStrategy, "useAccountPercentEntry", strategy.UseAccountPercentEntry);
            AppendStringElement(xmlDocStrategy, "entryLots", strategy.EntryLots);
            AppendStringElement(xmlDocStrategy, "addingLots", strategy.AddingLots);
            AppendStringElement(xmlDocStrategy, "reducingLots", strategy.ReducingLots);
            AppendStringElement(xmlDocStrategy, "useMartingale", strategy.UseMartingale);
            AppendStringElement(xmlDocStrategy, "martingaleMultiplier", strategy.MartingaleMultiplier);
            AppendStringElement(xmlDocStrategy, "description", strategy.Description);

            // Add the slots.
            AppendStringElement(xmlDocStrategy, "openFilters", strategy.OpenFilters);
            AppendStringElement(xmlDocStrategy, "closeFilters", strategy.CloseFilters);
            for (int slot = 0; slot < strategy.Slots; slot++)
            {
                IndicatorSlot stratSlot = strategy.Slot[slot];
                SlotTypes     slType    = stratSlot.SlotType;

                // Add a slot element.
                XmlElement newSlot = xmlDocStrategy.CreateElement("slot");
                newSlot.SetAttribute("slotNumber", slot.ToString(CultureInfo.InvariantCulture));
                newSlot.SetAttribute("slotType", slType.ToString());
                newSlot.SetAttribute("slotStatus", stratSlot.SlotStatus.ToString());

                if (slType == SlotTypes.OpenFilter || slType == SlotTypes.CloseFilter)
                {
                    newSlot.SetAttribute("logicalGroup", stratSlot.LogicalGroup);
                }

                // Add an element.
                newElem           = xmlDocStrategy.CreateElement("indicatorName");
                newElem.InnerText = stratSlot.IndicatorName;
                newSlot.AppendChild(newElem);

                // Add the list parameters.
                for (int param = 0; param < stratSlot.IndParam.ListParam.Length; param++)
                {
                    if (!stratSlot.IndParam.ListParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newListElem = xmlDocStrategy.CreateElement("listParam");
                    newListElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Caption;
                    newListElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("index");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Index.ToString(CultureInfo.InvariantCulture);
                    newListElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText = stratSlot.IndParam.ListParam[param].Text;
                    newListElem.AppendChild(newElem);

                    newSlot.AppendChild(newListElem);
                }

                // Add the num parameters.
                for (int param = 0; param < stratSlot.IndParam.NumParam.Length; param++)
                {
                    if (!stratSlot.IndParam.NumParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newNumElem = xmlDocStrategy.CreateElement("numParam");
                    newNumElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.NumParam[param].Caption;
                    newNumElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText = stratSlot.IndParam.NumParam[param].ValueToString;
                    newNumElem.AppendChild(newElem);

                    newSlot.AppendChild(newNumElem);
                }

                // Add the check parameters.
                for (int param = 0; param < stratSlot.IndParam.CheckParam.Length; param++)
                {
                    if (!stratSlot.IndParam.CheckParam[param].Enabled)
                    {
                        continue;
                    }

                    // Add an element.
                    XmlElement newCheckElem = xmlDocStrategy.CreateElement("checkParam");
                    newCheckElem.SetAttribute("paramNumber", param.ToString(CultureInfo.InvariantCulture));

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("caption");
                    newElem.InnerText = stratSlot.IndParam.CheckParam[param].Caption;
                    newCheckElem.AppendChild(newElem);

                    // Add an element.
                    newElem           = xmlDocStrategy.CreateElement("value");
                    newElem.InnerText =
                        stratSlot.IndParam.CheckParam[param].Checked.ToString(CultureInfo.InvariantCulture);
                    newCheckElem.AppendChild(newElem);

                    newSlot.AppendChild(newCheckElem);
                }

                if (xmlDocStrategy.DocumentElement != null)
                {
                    xmlDocStrategy.DocumentElement.AppendChild(newSlot);
                }
            }

            // Add statistics meta data.
            string unit = " " + Configs.AccountCurrency;

            AppendStringElement(xmlDocStrategy, "AccountBalance", Backtester.NetMoneyBalance.ToString("F2") + unit);
            AppendStringElement(xmlDocStrategy, "ProfitPerDay", Backtester.MoneyProfitPerDay.ToString("F2") + unit);
            AppendStringElement(xmlDocStrategy, "WinLossRatio", Backtester.WinLossRatio.ToString("F2"));
            AppendStringElement(xmlDocStrategy, "AccountStatsParam", String.Join(";", Backtester.AccountStatsParam));
            AppendStringElement(xmlDocStrategy, "AccountStatsValue", String.Join(";", Backtester.AccountStatsValue));
            AppendStringElement(xmlDocStrategy, "MarketStatsParam", String.Join(";", Data.MarketStatsParam));
            AppendStringElement(xmlDocStrategy, "MarketStatsValue", String.Join(";", Data.MarketStatsValue));

            // Add chart data
            int length      = Data.Bars - StatsBuffer.FirstBar;
            var balanceLine = new double[length];
            var equityLine  = new double[length];

            for (int bar = 0; bar < length; bar++)
            {
                balanceLine[bar] = Backtester.MoneyBalance(bar);
                equityLine[bar]  = Backtester.MoneyEquity(bar);
            }
            int size = Math.Min(600, length);

            string[] balanceList = MathUtils.ArrayToStringArray(MathUtils.ArrayResize(balanceLine, size));
            string[] equityList  = MathUtils.ArrayToStringArray(MathUtils.ArrayResize(equityLine, size));
            AppendStringElement(xmlDocStrategy, "BalanceLine", String.Join(";", balanceList));
            AppendStringElement(xmlDocStrategy, "EquityLine", String.Join(";", equityList));

            return(xmlDocStrategy);
        }