/// <summary> /// Load Source Files /// </summary> public static void LoadCustomIndicators() { _indicatorManager = new IndicatorCompilationManager(); if (!Directory.Exists(Data.SourceFolder)) { MessageBox.Show("Custom indicators folder does not exist!", Language.T("Custom Indicators")); IndicatorStore.ResetCustomIndicators(null); IndicatorStore.CombineAllIndicators(); return; } string[] pathInputFiles = Directory.GetFiles(Data.SourceFolder, "*.cs"); if (pathInputFiles.Length == 0) { IndicatorStore.ResetCustomIndicators(null); IndicatorStore.CombineAllIndicators(); return; } var errorReport = new StringBuilder(); errorReport.AppendLine("<h1>" + Language.T("Custom Indicators") + "</h1>"); bool isError = false; foreach (string filePath in pathInputFiles) { string errorMessages; _indicatorManager.LoadCompileSourceFile(filePath, out errorMessages); if (!string.IsNullOrEmpty(errorMessages)) { isError = true; errorReport.AppendLine("<h2>File name: " + Path.GetFileName(filePath) + "</h2>"); string error = errorMessages.Replace(Environment.NewLine, "</br>"); error = error.Replace("\t", " "); errorReport.AppendLine("<p>" + error + "</p>"); } } // Adds the custom indicators IndicatorStore.ResetCustomIndicators(_indicatorManager.CustomIndicatorsList); IndicatorStore.CombineAllIndicators(); if (isError) { var msgBox = new FancyMessageBox(errorReport.ToString(), Language.T("Custom Indicators")) { BoxWidth = 550, BoxHeight = 340, TopMost = true }; msgBox.Show(); } if (Configs.ShowCustomIndicators) { ShowLoadedCustomIndicators(); } }
/// <summary> /// Loads the default parameters for the selected indicator. /// </summary> private void BtnDefaultClick(object sender, EventArgs e) { Indicator indicator = IndicatorStore.ConstructIndicator(_indicatorName, _slotType); UpdateFromIndicatorParam(indicator.IndParam); SetDefaultGroup(); CalculateIndicator(true); UpdateBalanceChart(); }
/// <summary> /// Loads an Indicator /// </summary> private void TrvIndicatorsLoadIndicator() { Indicator indicator = IndicatorStore.ConstructIndicator(TrvIndicators.SelectedNode.Text, _slotType); UpdateFromIndicatorParam(indicator.IndParam); SetDefaultGroup(); CalculateIndicator(true); UpdateBalanceChart(); }
/// <summary> /// Sets Use previous bar value automatically /// </summary> public bool AdjustUsePreviousBarValue() { bool isSomethingChanged = false; if (Data.AutoUsePrvBarValue == false) { return(false); } for (int slot = 0; slot < Slots; slot++) { isSomethingChanged = SetUsePrevBarValueCheckBox(slot) || isSomethingChanged; } // Recalculates the indicators. if (isSomethingChanged) { for (int slot = 0; slot < Slots; slot++) { string sIndicatorName = Data.Strategy.Slot[slot].IndicatorName; SlotTypes slotType = Data.Strategy.Slot[slot].SlotType; Indicator indicator = IndicatorStore.ConstructIndicator(sIndicatorName, slotType); indicator.IndParam = Data.Strategy.Slot[slot].IndParam; indicator.Calculate(slotType); // Set the Data.Strategy Slot[slot].IndicatorName = indicator.IndicatorName; Slot[slot].IndParam = indicator.IndParam; Slot[slot].Component = indicator.Component; Slot[slot].SeparatedChart = indicator.SeparatedChart; Slot[slot].SpecValue = indicator.SpecialValues; Slot[slot].MinValue = indicator.SeparatedChartMinValue; Slot[slot].MaxValue = indicator.SeparatedChartMaxValue; Slot[slot].IsDefined = true; } } return(isSomethingChanged); }
/// <summary> /// Show indicators in the selected bars. /// </summary> private void ShowIndicators(string input) { const string pattern = @"^ind (?<numb>\d+)$"; var expression = new Regex(pattern, RegexOptions.Compiled); Match match = expression.Match(input); if (match.Success) { int bar = int.Parse(match.Groups["numb"].Value); if (bar < 1 || bar > Data.Bars) { return; } bar--; var sb = new StringBuilder(); for (int iSlot = 0; iSlot < Data.Strategy.Slots; iSlot++) { Indicator indicator = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[iSlot].IndicatorName, Data.Strategy.Slot[iSlot].SlotType); sb.Append(Environment.NewLine + indicator + Environment.NewLine + "Logic: " + indicator.IndParam.ListParam[0].Text + Environment.NewLine + "-----------------" + Environment.NewLine); foreach (IndicatorComp indComp in Data.Strategy.Slot[iSlot].Component) { sb.Append(indComp.CompName + " "); sb.Append(indComp.Value[bar] + Environment.NewLine); } } TbxOutput.Text += Environment.NewLine + "Indicators for bar " + (bar + 1) + Environment.NewLine + "-----------------" + Environment.NewLine + sb; } }
/// <summary> /// Exports data and indicators values /// </summary> public void ExportIndicators() { string stage = String.Empty; if (Data.IsProgramBeta) { stage = " " + Language.T("Beta"); } else if (Data.IsProgramRC) { stage = " " + "RC"; } string ff = Data.FF; // Format modifier to print float numbers string df = Data.DF; // Format modifier to print date var sb = new StringBuilder(); sb.Append("Forex Strategy Builder v" + Data.ProgramVersion + stage + Environment.NewLine); sb.Append("Strategy name: " + Data.Strategy.StrategyName + Environment.NewLine); sb.Append("Exported on " + DateTime.Now + Environment.NewLine); sb.Append(Data.Symbol + " " + Data.PeriodString + Environment.NewLine); sb.Append("Number of bars: " + Data.Bars); sb.Append("\t\t\t\t\t\t\t\t"); for (int slot = 0; slot < Data.Strategy.Slots; slot++) { string strSlotType = ""; switch (Data.Strategy.Slot[slot].SlotType) { case SlotTypes.Open: strSlotType = "Opening point of the position"; break; case SlotTypes.OpenFilter: strSlotType = "Opening logic condition"; break; case SlotTypes.Close: strSlotType = "Closing point of the position"; break; case SlotTypes.CloseFilter: strSlotType = "Closing logic condition"; break; } sb.Append(strSlotType + "\t"); for (int i = 0; i < Data.Strategy.Slot[slot].Component.Length; i++) { sb.Append("\t"); } } sb.Append(Environment.NewLine); // Names of the indicator components sb.Append("\t\t\t\t\t\t\t\t"); for (int slot = 0; slot < Data.Strategy.Slots; slot++) { Indicator indicator = IndicatorStore.ConstructIndicator(Data.Strategy.Slot[slot].IndicatorName, Data.Strategy.Slot[slot].SlotType); sb.Append(indicator + "\t"); for (int i = 0; i < Data.Strategy.Slot[slot].Component.Length; i++) { sb.Append("\t"); } } sb.Append(Environment.NewLine); // Data sb.Append("Date" + "\t"); sb.Append("Hour" + "\t"); sb.Append("Open" + "\t"); sb.Append("High" + "\t"); sb.Append("Low" + "\t"); sb.Append("Close" + "\t"); sb.Append("Volume" + "\t"); for (int slot = 0; slot < Data.Strategy.Slots; slot++) { sb.Append("\t"); foreach (IndicatorComp comp in Data.Strategy.Slot[slot].Component) { sb.Append(comp.CompName + "\t"); } } sb.Append(Environment.NewLine); for (int bar = 0; bar < Data.Bars; bar++) { sb.Append(Data.Time[bar].ToString(df) + "\t"); sb.Append(Data.Time[bar].ToString("HH:mm") + "\t"); sb.Append(Data.Open[bar].ToString(ff) + "\t"); sb.Append(Data.High[bar].ToString(ff) + "\t"); sb.Append(Data.Low[bar].ToString(ff) + "\t"); sb.Append(Data.Close[bar].ToString(ff) + "\t"); sb.Append(Data.Volume[bar] + "\t"); for (int slot = 0; slot < Data.Strategy.Slots; slot++) { sb.Append("\t"); foreach (IndicatorComp comp in Data.Strategy.Slot[slot].Component) { sb.Append(comp.Value[bar] + "\t"); } } sb.Append(Environment.NewLine); } string fileName = Data.Strategy.StrategyName + "-" + Data.Symbol + "-" + Data.Period; SaveData(fileName, sb); }
/// <summary> /// Calculates the selected indicator. /// </summary> private void CalculateIndicator(bool bCalculateStrategy) { if (!Data.IsData || !Data.IsResult || !_isPaint) { return; } SetOppositeSignalBehaviour(); SetClosingLogicConditions(); Indicator indicator = IndicatorStore.ConstructIndicator(_indicatorName, _slotType); // List parameters for (int i = 0; i < 5; i++) { indicator.IndParam.ListParam[i].Index = ListParam[i].SelectedIndex; indicator.IndParam.ListParam[i].Text = ListParam[i].Text; indicator.IndParam.ListParam[i].Enabled = ListParam[i].Enabled; } // Numeric parameters for (int i = 0; i < 6; i++) { indicator.IndParam.NumParam[i].Value = (double)NumParam[i].Value; indicator.IndParam.NumParam[i].Enabled = NumParam[i].Enabled; } // Check parameters for (int i = 0; i < 2; i++) { indicator.IndParam.CheckParam[i].Checked = CheckParam[i].Checked; indicator.IndParam.CheckParam[i].Enabled = CheckParam[i].Enabled; indicator.IndParam.CheckParam[i].Enabled = CheckParam[i].Text == "Use previous bar value" || CheckParam[i].Enabled; } if (!CalculateIndicator(_slotType, indicator)) { return; } if (bCalculateStrategy) { //Sets Data.Strategy Data.Strategy.Slot[_slot].IndicatorName = indicator.IndicatorName; Data.Strategy.Slot[_slot].IndParam = indicator.IndParam; Data.Strategy.Slot[_slot].Component = indicator.Component; Data.Strategy.Slot[_slot].SeparatedChart = indicator.SeparatedChart; Data.Strategy.Slot[_slot].SpecValue = indicator.SpecialValues; Data.Strategy.Slot[_slot].MinValue = indicator.SeparatedChartMinValue; Data.Strategy.Slot[_slot].MaxValue = indicator.SeparatedChartMaxValue; Data.Strategy.Slot[_slot].IsDefined = true; // Search the indicators' components to determine Data.FirstBar Data.FirstBar = Data.Strategy.SetFirstBar(); // Check "Use previous bar value" if (Data.Strategy.AdjustUsePreviousBarValue()) { for (int i = 0; i < 2; i++) { if (indicator.IndParam.CheckParam[i].Caption == "Use previous bar value") { AChbCheck[i].Checked = Data.Strategy.Slot[_slot].IndParam.CheckParam[i].Checked; } } } Backtester.Calculate(); Backtester.CalculateAccountStats(); } SetIndicatorNotification(indicator); Data.IsResult = true; }
/// <summary> /// Sets the trvIndicators nodes /// </summary> private void SetTreeViewIndicators() { var trnAll = new TreeNode { Name = "trnAll", Text = Language.T("All"), Tag = false }; var trnIndicators = new TreeNode { Name = "trnIndicators", Text = Language.T("Indicators"), Tag = false }; var trnAdditional = new TreeNode { Name = "trnAdditional", Text = Language.T("Additional"), Tag = false }; var trnOscillatorOfIndicators = new TreeNode { Name = "trnOscillatorOfIndicators", Text = Language.T("Oscillator of Indicators"), Tag = false }; var trnIndicatorsMAOscillator = new TreeNode { Name = "trnIndicatorMA", Text = Language.T("Indicator's MA Oscillator"), Tag = false }; var trnDateTime = new TreeNode { Name = "trnDateTime", Text = Language.T("Date/Time Functions"), Tag = false }; var trnCustomIndicators = new TreeNode { Name = "trnCustomIndicators", Text = Language.T("Custom Indicators"), Tag = false }; TrvIndicators.Nodes.AddRange(new[] { trnAll, trnIndicators, trnAdditional, trnOscillatorOfIndicators, trnIndicatorsMAOscillator, trnDateTime, trnCustomIndicators }); foreach (string name in IndicatorStore.GetIndicatorNames(_slotType)) { var trn = new TreeNode { Tag = true, Name = name, Text = name }; trnAll.Nodes.Add(trn); Indicator indicator = IndicatorStore.ConstructIndicator(name, _slotType); TypeOfIndicator type = indicator.IndParam.IndicatorType; if (indicator.CustomIndicator) { var trnCustom = new TreeNode { Tag = true, Name = name, Text = name }; trnCustomIndicators.Nodes.Add(trnCustom); } var trnGroups = new TreeNode { Tag = true, Name = name, Text = name }; switch (type) { case TypeOfIndicator.Indicator: trnIndicators.Nodes.Add(trnGroups); break; case TypeOfIndicator.Additional: trnAdditional.Nodes.Add(trnGroups); break; case TypeOfIndicator.OscillatorOfIndicators: trnOscillatorOfIndicators.Nodes.Add(trnGroups); break; case TypeOfIndicator.IndicatorsMA: trnIndicatorsMAOscillator.Nodes.Add(trnGroups); break; case TypeOfIndicator.DateTime: trnDateTime.Nodes.Add(trnGroups); break; } } }
/// <summary> /// Performs thorough indicator test. /// </summary> /// <param name="indicatorName">The indicator name.</param> /// <param name="errorsList">Error message.</param> /// <returns>True, if the test succeed.</returns> public static bool CustomIndicatorThoroughTest(string indicatorName, out string errorsList) { bool isOk = true; var sb = new StringBuilder(); sb.AppendLine("ERROR: Indicator test failed for the '" + indicatorName + "' indicator."); foreach (SlotTypes slotType in Enum.GetValues(typeof(SlotTypes))) { if (slotType == SlotTypes.NotDefined) { continue; } Indicator indicator = IndicatorStore.ConstructIndicator(indicatorName, slotType); if (!indicator.TestPossibleSlot(slotType)) { continue; } foreach (NumericParam numParam in indicator.IndParam.NumParam) { if (numParam.Enabled) { numParam.Value = numParam.Min; } } try { indicator.Calculate(slotType); } catch (Exception exc) { sb.AppendLine("\tError when calculating with NumParams set to their minimal values. " + exc.Message); isOk = false; break; } foreach (NumericParam numParam in indicator.IndParam.NumParam) { if (numParam.Enabled) { numParam.Value = numParam.Max; } } try { indicator.Calculate(slotType); } catch (Exception exc) { sb.AppendLine("\tError when calculating with NumParams set to their maximal values. " + exc.Message); isOk = false; break; } try { foreach (IndicatorComp component in indicator.Component) { switch (slotType) { case SlotTypes.Open: if (component.DataType == IndComponentType.AllowOpenLong || component.DataType == IndComponentType.AllowOpenShort || component.DataType == IndComponentType.CloseLongPrice || component.DataType == IndComponentType.ClosePrice || component.DataType == IndComponentType.CloseShortPrice || component.DataType == IndComponentType.ForceClose || component.DataType == IndComponentType.ForceCloseLong || component.DataType == IndComponentType.ForceCloseShort || component.DataType == IndComponentType.NotDefined) { sb.AppendLine( "\tProbably wrong component type when SlotType is 'SlotTypes.Open' - '" + component.CompName + "' of type '" + component.DataType + "'."); isOk = false; } break; case SlotTypes.OpenFilter: if (component.DataType == IndComponentType.OpenClosePrice || component.DataType == IndComponentType.OpenLongPrice || component.DataType == IndComponentType.OpenPrice || component.DataType == IndComponentType.OpenShortPrice || component.DataType == IndComponentType.CloseLongPrice || component.DataType == IndComponentType.ClosePrice || component.DataType == IndComponentType.CloseShortPrice || component.DataType == IndComponentType.ForceClose || component.DataType == IndComponentType.ForceCloseLong || component.DataType == IndComponentType.ForceCloseShort || component.DataType == IndComponentType.NotDefined) { sb.AppendLine( "\tProbably wrong component type when SlotType is 'SlotTypes.OpenFilter' - '" + component.CompName + "' of type '" + component.DataType + "'."); isOk = false; } break; case SlotTypes.Close: if (component.DataType == IndComponentType.AllowOpenLong || component.DataType == IndComponentType.AllowOpenShort || component.DataType == IndComponentType.OpenLongPrice || component.DataType == IndComponentType.OpenPrice || component.DataType == IndComponentType.OpenShortPrice || component.DataType == IndComponentType.ForceClose || component.DataType == IndComponentType.ForceCloseLong || component.DataType == IndComponentType.ForceCloseShort || component.DataType == IndComponentType.NotDefined) { sb.AppendLine( "\tProbably wrong component type when SlotType is 'SlotTypes.Close' - '" + component.CompName + "' of type '" + component.DataType + "'."); isOk = false; } break; case SlotTypes.CloseFilter: if (component.DataType == IndComponentType.AllowOpenLong || component.DataType == IndComponentType.AllowOpenShort || component.DataType == IndComponentType.OpenLongPrice || component.DataType == IndComponentType.OpenPrice || component.DataType == IndComponentType.OpenShortPrice || component.DataType == IndComponentType.CloseLongPrice || component.DataType == IndComponentType.ClosePrice || component.DataType == IndComponentType.CloseShortPrice || component.DataType == IndComponentType.NotDefined) { sb.AppendLine( "\tProbably wrong component type when SlotType is 'SlotTypes.CloseFilter' - '" + component.CompName + "' of type '" + component.DataType + "'."); isOk = false; } break; } if (component.DataType == IndComponentType.AllowOpenLong || component.DataType == IndComponentType.AllowOpenShort || component.DataType == IndComponentType.ForceClose || component.DataType == IndComponentType.ForceCloseLong || component.DataType == IndComponentType.ForceCloseShort) { foreach (double value in component.Value) { if (value != 0 && value != 1) { sb.AppendLine("\tWrong component values. The values of '" + component.CompName + "' must be 0 or 1."); isOk = false; break; } } } } } catch (Exception exc) { sb.AppendLine("\tError when checking the indicator's components. " + exc.Message); isOk = false; break; } } errorsList = isOk ? string.Empty : sb.ToString(); return(isOk); }
/// <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. var tempStrategy = new Strategy(openFilters, closeFilters); // 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; tempStrategy.DataPeriod = (DataPeriods) Enum.Parse(typeof(DataPeriods), xmlDocStrategy.GetElementsByTagName("instrumentPeriod")[0].InnerText); // 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; XmlAttributeCollection collection = xmlSlotList[slot].Attributes; if (collection != null) { 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; tempStrategy.Slot[slot].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 { tempStrategy.Slot[slot].LogicalGroup = defGroup; } } // Indicator name. string indicatorName = xmlSlotTagList[0].InnerText; Indicator indicator = IndicatorStore.ConstructIndicator(indicatorName, 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); } } } } // Calculate the indicator. indicator.Calculate(slotType); tempStrategy.Slot[slot].IndicatorName = indicator.IndicatorName; tempStrategy.Slot[slot].IndParam = indicator.IndParam; tempStrategy.Slot[slot].Component = indicator.Component; tempStrategy.Slot[slot].SeparatedChart = indicator.SeparatedChart; tempStrategy.Slot[slot].SpecValue = indicator.SpecialValues; tempStrategy.Slot[slot].MinValue = indicator.SeparatedChartMinValue; tempStrategy.Slot[slot].MaxValue = indicator.SeparatedChartMaxValue; } tempStrategy.Slot[slot].IsDefined = true; } return(tempStrategy); }