/// <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); }
/// <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]; } }
/// <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; } }
/// <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; }
/// <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; }
/// <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); }