/// <summary>
        /// Helper, initialize a single TaLib indicator.
        /// </summary>
        Indicator InitializeTaLibIndicator(MethodInfo methodInfo, string indicatorName, bool?isTradeable,
                                           bool?isScaledToQuotes, float?rangeMinimum, float?rangeMaximum, DataBar.DataValueEnum?inRealSource, DataBar.DataValueEnum?inReal1Source, params object[] inputParameters)
        {
            lock (this)
            {
                MethodInfo lookBackCountMethodInfo = null;
                foreach (MethodInfo info in typeof(TicTacTec.TA.Library.Core).GetMethods())
                {
                    if (info.Name == methodInfo.Name + "Lookback")
                    {
                        lookBackCountMethodInfo = info;
                        break;
                    }
                }

                if (lookBackCountMethodInfo == null)
                {
                    SystemMonitor.Error("Failed to find indicator [" + methodInfo.Name + "] look back method.");
                    return(null);
                }

                GenericTALibIndicator indicator = GenericTALibIndicator.CreateInstance(methodInfo, lookBackCountMethodInfo, indicatorName, isTradeable, isScaledToQuotes);

                if (indicator == null)
                {
                    SystemMonitor.Error("Creating indicator [" + indicator.Name + "] failed.");
                    return(null);
                }

                string[] names = new string[inputParameters.Length];
                for (int i = 0; i < inputParameters.Length; i++)
                {
                    names[i] = "Parameter." + inputParameters[i].GetType().Name + "." + i.ToString();
                }

                SystemMonitor.CheckThrow(indicator.SetInitialParameters(inputParameters, names));

                _indicatorsGroups[IndicatorGroup.TaLib].Add(indicator.Name, indicator);

                indicator.RealInputArraySource  = inRealSource;
                indicator.Real1InputArraySource = inReal1Source;

                indicator.RangeMinimum = rangeMinimum;
                indicator.RangeMaximum = rangeMaximum;

                return(indicator);
            }
        }
        /// <summary>
        /// Does not include results.
        /// </summary>
        /// <returns></returns>
        public override PlatformIndicator OnSimpleClone()
        {
            TracerHelper.Trace((this.DataProvider != null).ToString());

            GenericTALibIndicator newIndicator = CreateInstance(_methodInfo, _lookbackMethodInfo, Description, Tradeable, ScaledToQuotes);

            newIndicator._inputDefaultArrayParameters = new List <ParameterInfo>(_inputDefaultArrayParameters);
            newIndicator._intputParameters            = new List <ParameterInfo>(_intputParameters);
            newIndicator._outputArraysParameters      = new List <ParameterInfo>(_outputArraysParameters);
            newIndicator._parameters = (IndicatorParameters)_parameters.Clone();

            newIndicator._realInputArraySource  = _realInputArraySource;
            newIndicator._real1InputArraySource = _real1InputArraySource;

            return(newIndicator);
        }
        /// <summary>
        /// Static construction routine; needed since the way TaLib indicators are constructed is dynamically.
        /// </summary>
        public static GenericTALibIndicator CreateInstance(MethodInfo methodInfo, MethodInfo lookbackMethodInfo, string description, bool? isTradeable, bool? isScaledToQuotes)
        {
            if (methodInfo == null)
            {
                return null;
            }

            Type returnType = methodInfo.ReturnType;

            if (returnType != typeof(TicTacTec.TA.Library.Core.RetCode))
            {
                return null;
            }

            ParameterInfo[] parameters = methodInfo.GetParameters();
            if (parameters.Length < 5)
            {
                return null;
            }

            int index = 0;

            if (parameters[index].ParameterType != typeof(int) ||
                parameters[index].Name != "startIdx")
            {
                return null;
            }
            index++;

            if (parameters[index].ParameterType != typeof(int) ||
                parameters[index].Name != "endIdx")
            {
                return null;
            }
            index++;

            List<ParameterInfo> indicatorParameters = new List<ParameterInfo>();
            while (parameters.Length > index && parameters[index].ParameterType == typeof(double[]))
            {
                if (parameters[index].Name != "inReal" &&
                    parameters[index].Name != "inReal0" &&
                    parameters[index].Name != "inReal1" &&
                    parameters[index].Name != "inHigh" &&
                    parameters[index].Name != "inLow" &&
                    parameters[index].Name != "inOpen" &&
                    parameters[index].Name != "inClose" &&
                    parameters[index].Name != "inVolume"
                    )
                {
                    return null;
                }

                indicatorParameters.Add(parameters[index]);
                index++;
            }

            // optIn parameters
            List<ParameterInfo> indicatorInputParameters = new List<ParameterInfo>();
            while(parameters.Length > index && parameters[index].Name.StartsWith("optIn"))
            {
                if (parameters[index].ParameterType == typeof(int) ||
                    parameters[index].ParameterType != typeof(double) ||
                    parameters[index].ParameterType != typeof(TicTacTec.TA.Library.Core.MAType))
                {
                    indicatorInputParameters.Add(parameters[index]);
                }
                else
                {// Invalid type.
                    return null;
                }
                index++;
            }

            if (parameters.Length <= index || parameters[index].IsOut == false
                || parameters[index].Name != "outBegIdx")
            {
                return null;
            }

            index++;

            if (parameters.Length <= index || parameters[index].IsOut == false
                || parameters[index].Name != "outNBElement")
            {
                return null;
            }

            index++;

            List<ParameterInfo> indicatorOutputArrayParameters = new List<ParameterInfo>();
            List<string> indicatorOutputArrayParametersNames = new List<string>();
            while (parameters.Length > index)
            {
                if (parameters[index].Name.StartsWith("out") == false)
                {
                    return null;
                }

                if (parameters[index].ParameterType == typeof(double[])
                    || parameters[index].ParameterType == typeof(int[]))
                {
                    indicatorOutputArrayParametersNames.Add(parameters[index].Name);
                    indicatorOutputArrayParameters.Add(parameters[index]);
                }
                else
                {
                    return null;
                }

                index++;
            }

            if (parameters.Length != index)
            {// Parameters left unknown.
                return null;
            }

            GenericTALibIndicator indicator = new GenericTALibIndicator(methodInfo.Name, description, isTradeable, isScaledToQuotes, indicatorOutputArrayParametersNames.ToArray());
            indicator._inputDefaultArrayParameters.AddRange(indicatorParameters);
            indicator._outputArraysParameters.AddRange(indicatorOutputArrayParameters);
            indicator._intputParameters.AddRange(indicatorInputParameters);
            indicator._methodInfo = methodInfo;
            indicator._lookbackMethodInfo = lookbackMethodInfo;

            return indicator;
        }
        /// <summary>
        /// Static construction routine; needed since the way TaLib indicators are constructed is dynamically.
        /// </summary>
        public static GenericTALibIndicator CreateInstance(MethodInfo methodInfo, MethodInfo lookbackMethodInfo, string description, bool?isTradeable, bool?isScaledToQuotes)
        {
            if (methodInfo == null)
            {
                return(null);
            }

            Type returnType = methodInfo.ReturnType;

            if (returnType != typeof(TicTacTec.TA.Library.Core.RetCode))
            {
                return(null);
            }

            ParameterInfo[] parameters = methodInfo.GetParameters();
            if (parameters.Length < 5)
            {
                return(null);
            }

            int index = 0;

            if (parameters[index].ParameterType != typeof(int) ||
                parameters[index].Name != "startIdx")
            {
                return(null);
            }
            index++;

            if (parameters[index].ParameterType != typeof(int) ||
                parameters[index].Name != "endIdx")
            {
                return(null);
            }
            index++;

            List <ParameterInfo> indicatorParameters = new List <ParameterInfo>();

            while (parameters.Length > index && parameters[index].ParameterType == typeof(double[]))
            {
                if (parameters[index].Name != "inReal" &&
                    parameters[index].Name != "inReal0" &&
                    parameters[index].Name != "inReal1" &&
                    parameters[index].Name != "inHigh" &&
                    parameters[index].Name != "inLow" &&
                    parameters[index].Name != "inOpen" &&
                    parameters[index].Name != "inClose" &&
                    parameters[index].Name != "inVolume"
                    )
                {
                    return(null);
                }

                indicatorParameters.Add(parameters[index]);
                index++;
            }

            // optIn parameters
            List <ParameterInfo> indicatorInputParameters = new List <ParameterInfo>();

            while (parameters.Length > index && parameters[index].Name.StartsWith("optIn"))
            {
                if (parameters[index].ParameterType == typeof(int) ||
                    parameters[index].ParameterType != typeof(double) ||
                    parameters[index].ParameterType != typeof(TicTacTec.TA.Library.Core.MAType))
                {
                    indicatorInputParameters.Add(parameters[index]);
                }
                else
                {// Invalid type.
                    return(null);
                }
                index++;
            }

            if (parameters.Length <= index || parameters[index].IsOut == false ||
                parameters[index].Name != "outBegIdx")
            {
                return(null);
            }

            index++;

            if (parameters.Length <= index || parameters[index].IsOut == false ||
                parameters[index].Name != "outNBElement")
            {
                return(null);
            }

            index++;

            List <ParameterInfo> indicatorOutputArrayParameters      = new List <ParameterInfo>();
            List <string>        indicatorOutputArrayParametersNames = new List <string>();

            while (parameters.Length > index)
            {
                if (parameters[index].Name.StartsWith("out") == false)
                {
                    return(null);
                }

                if (parameters[index].ParameterType == typeof(double[]) ||
                    parameters[index].ParameterType == typeof(int[]))
                {
                    indicatorOutputArrayParametersNames.Add(parameters[index].Name);
                    indicatorOutputArrayParameters.Add(parameters[index]);
                }
                else
                {
                    return(null);
                }

                index++;
            }

            if (parameters.Length != index)
            {// Parameters left unknown.
                return(null);
            }

            GenericTALibIndicator indicator = new GenericTALibIndicator(methodInfo.Name, description, isTradeable, isScaledToQuotes, indicatorOutputArrayParametersNames.ToArray());

            indicator._inputDefaultArrayParameters.AddRange(indicatorParameters);
            indicator._outputArraysParameters.AddRange(indicatorOutputArrayParameters);
            indicator._intputParameters.AddRange(indicatorInputParameters);
            indicator._methodInfo         = methodInfo;
            indicator._lookbackMethodInfo = lookbackMethodInfo;

            return(indicator);
        }