예제 #1
0
        private void loadButtons()
        {
            int itterator = 0;

            BtnListFunctions = new List <Button>();
            BtnListVariables = new List <Button>();

            foreach (Fn func in RuleParserInputs.Fns)
            {
                BtnListFunctions.Add(new Button());
                BtnListFunctions[itterator].Text   = StringEnum.GetStringValue(func);
                BtnListFunctions[itterator].Click += new EventHandler(this.analysisBtnFunc_OnClick);
                this.flpFunctions.Controls.Add(BtnListFunctions[itterator]);
                itterator++;
            }

            itterator = 0;
            foreach (Variable vEn in RuleParserInputs.VarList)
            {
                BtnListVariables.Add(new Button());
                BtnListVariables[itterator].Text   = RuleParserInputs.VarCaptions[itterator];
                BtnListVariables[itterator].Click += new EventHandler(this.analysisBtnVar_OnClick);
                this.flpVariables.Controls.Add(BtnListVariables[itterator]);
                itterator++;
            }
        }
예제 #2
0
        /*****************************************************************************
        *  FUNCTION:       InitializeDefaultValues
        *  Description:
        *  Parameters:     None
        *****************************************************************************/
        private void InitializeDefaultValues()
        {
            int i;

            this.numTrainingPct.Value = this.trackBarTrainingPct.Value;
            this.numTestPct.Value     = ONE_HUNDRED_PCT - this.numTrainingPct.Value;

            for (i = 0; i < AlgSelectList.Length; i++)
            {
                this.algorithmSelectListBox.Items.Add(StringEnum.GetStringValue(AlgSelectList[i]));
            }

            for (i = 0; i < ClassKeyList.Length; i++)
            {
                this.cbProtoAttributeX.Items.Add(StringEnum.GetStringValue(ClassKeyList[i]));
            }

            for (i = 0; i < ClassKeyList.Length; i++)
            {
                this.cbProtoAttributeY.Items.Add(StringEnum.GetStringValue(ClassKeyList[i]));
            }

            for (i = 0; i < ClassFnList.Length; i++)
            {
                this.cbProtoFunction.Items.Add(StringEnum.GetStringValue(ClassFnList[i]));
            }
        }
예제 #3
0
        private void loadButtons()
        {
            int itterator = 0;
            int textLen   = 0;

            BtnListFunctions = new List <Button>();
            BtnListVariables = new List <Button>();

            foreach (Fn func in RuleParserInputs.Fns)
            {
                BtnListFunctions.Add(new Button());
                BtnListFunctions[itterator].Text   = StringEnum.GetStringValue(func);
                BtnListFunctions[itterator].Click += new EventHandler(this.analysisBtnFunc_OnClick);
                this.flpFunctions.Controls.Add(BtnListFunctions[itterator]);
                itterator++;
            }

            itterator = 0;
            foreach (Variable vEn in RuleParserInputs.VarList)
            {
                textLen = RuleParserInputs.VarCaptions[itterator].Length;
                BtnListVariables.Add(new Button());
                BtnListVariables[itterator].Text   = RuleParserInputs.VarCaptions[itterator];
                BtnListVariables[itterator].Click += new EventHandler(this.analysisBtnVar_OnClick);
                this.flpVariables.Controls.Add(BtnListVariables[itterator]);

                //Increase the size of the button if necessary to get all text to fit on 1 line
                if (textLen > 9)
                {
                    BtnListVariables[itterator].Width += (textLen - 9) * 8;
                }
                itterator++;
            }
        }
예제 #4
0
 private void cbProtoFunction_SelectedIndexChanged(object sender, EventArgs e)
 {
     if (this.DataSrc != null &&
         this.DataSrc.HistoricalData.Constituents.Count > 0 &&
         this.cbProtoFunction.SelectedItem.ToString() == StringEnum.GetStringValue(PrototypeFunction.DAILY))
     {
         BuildMovingChart();
     }
 }
예제 #5
0
        private int ExpressionStartIndex(string pRuleString, int pFromIndex)
        {
            int    nesting_level = 0, param_level = 0;
            int    index1  = 0;
            string tempStr = "";
            bool   isfound = false;

            //find the beginning of the expression first
            nesting_level = 0;
            param_level   = 0;
            isfound       = false;
            index1        = pFromIndex;
            while (index1 > 0)
            {
                switch (pRuleString[index1])
                {
                case '(':
                    nesting_level--;
                    break;

                case ')':
                    nesting_level++;
                    break;

                case '[':
                    param_level--;
                    break;

                case ']':
                    param_level++;
                    break;

                default:
                    break;
                }
                tempStr = pRuleString.SubWord(index1);

                if (RuleParserInputs.Fns.Where(a => StringEnum.GetStringValue(a) == tempStr).Count() > 0)
                {
                    isfound = true;
                }
                else if (RuleParserInputs.VarList.Where(a => StringEnum.GetStringValue(a) == tempStr).Count() > 0 &&
                         (param_level == 0))
                {
                    isfound = true;
                }

                if (isfound && (param_level == 0) && (nesting_level == 0))
                {
                    break;
                }

                index1--;
            }

            return(index1);
        }
예제 #6
0
        /*****************************************************************************
        *  FUNCTION:       Parse
        *  Description:    Replaces a primitive expression with corresponding numeric values
        *                  to enable evaluation.
        *
        *                  Ex. (P < AVG[P][-5..0])
        *  Parameters:
        *
        *****************************************************************************/
        private String Parse(String pExpression, Equity pEqIn, int pIndex, List <Fn> pFNs)
        {
            string parameter, str_expression, fn_str;
            double parameter_value = 0.0;

            string[] split_str;
            int      index1, index2;
            Variable in_param;

            str_expression = pExpression;
            foreach (Fn func in pFNs)
            {
                fn_str = "";
                if (pExpression.Contains(StringEnum.GetStringValue(func)))
                {
                    index1 = pExpression.IndexOf(StringEnum.GetStringValue(func));
                    index2 = pExpression.IndexOf("]", index1);

                    if (pExpression.Length > index2 && pExpression.ToCharArray()[index2 + 1] == '[')
                    {
                        index2 = pExpression.IndexOf("]", index2 + 1);
                    }

                    fn_str         = pExpression.Substring(index1, index2 - index1 + 1);
                    str_expression = str_expression.Replace(fn_str.Trim(), GetFunction(func, pEqIn, fn_str, pIndex).ToString());
                }
            }

            split_str = str_expression.Split(RuleParserInputs.Comparators, StringSplitOptions.RemoveEmptyEntries);

            foreach (string exp_part in split_str)
            {
                if (Helpers.ValidateNumeric(exp_part) == false)
                {
                    parameter = CleanExpression(exp_part.Trim());
                    in_param  = GetParameterType(parameter);

                    //If the data to be analyzed is one of the MACD signals, ensure the passed index is valid
                    if (in_param == Variable.MACD_DIFF || in_param == Variable.MACD_SIG)
                    {
                        if (pIndex > (pEqIn.HistoricalPrice.Count() - pEqIn.MACD_C.Count()))
                        {
                            parameter_value = GetParameter(pEqIn, parameter, pIndex);
                            str_expression  = str_expression.Replace(parameter, parameter_value.ToString());
                        }
                    }
                    else
                    {
                        parameter_value = GetParameter(pEqIn, parameter, pIndex);
                        str_expression  = str_expression.Replace(parameter, parameter_value.ToString());
                    }
                }
            }

            return(str_expression);
        }
예제 #7
0
        /*****************************************************************************
        *  FUNCTION:  ShowContextMenu
        *  Description:
        *  Parameters:
        *****************************************************************************/
        private void ShowContextMenu()
        {
            dataGridView1.ContextMenu.MenuItems.Clear();

            for (int i = 0; i < ContextMenuEntries.Count(); i++)
            {
                dataGridView1.ContextMenu.MenuItems.Add(StringEnum.GetStringValue(ContextMenuEntries[i]));
                dataGridView1.ContextMenu.MenuItems[i].Click += new EventHandler(dataGridView1_ContextMenuItemClick);
            }
        }
예제 #8
0
        private void BindChartData(List <double> x_values, List <double> y_values, List <int> classLabels)
        {
            List <List <double> > XDataByClass, YDataByClass;
            int    num_classes, i;
            string clbl_txt;
            Random randGen = new Random();

            if (x_values.Count == y_values.Count && x_values.Count == classLabels.Count)
            {
                ClearChart();

                num_classes  = classLabels.Max() + 1;
                XDataByClass = new List <List <double> >();
                YDataByClass = new List <List <double> >();

                for (i = 0; i < num_classes; i++)
                {
                    XDataByClass.Add(new List <double>());
                    YDataByClass.Add(new List <double>());
                }

                for (i = 0; i < x_values.Count; i++)
                {
                    XDataByClass[classLabels[i]].Add(x_values[i]);
                    YDataByClass[classLabels[i]].Add(y_values[i]);
                }

                //Bind data to chart
                for (i = 0; i < num_classes; i++)
                {
                    clbl_txt = "Class_" + (i + 1).ToString();
                    chartMain.Series.Add(clbl_txt);

                    chartMain.Series[clbl_txt].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
                    chartMain.Series[clbl_txt]["IsXAxisQuantitative"] = "true";
                    chartMain.Series[clbl_txt].Points.Clear();
                    chartMain.Series[clbl_txt].Points.DataBindXY(XDataByClass[i], YDataByClass[i]);
                    chartMain.Series[clbl_txt].MarkerStyle = MarkerStyle.Circle + (i % 10);
                    chartMain.Series[clbl_txt].MarkerSize  = 10;
                    chartMain.Series[clbl_txt].MarkerColor = Color.FromArgb(randGen.Next(100, 200), randGen.Next(100, 200), randGen.Next(100, 200));
                }

                //Set chart axes labels
                if (cbProtoAttributeX.SelectedIndex >= 0)
                {
                    chartMain.ChartAreas[0].AxisX.Title = StringEnum.GetStringValue(ClassKeyList[cbProtoAttributeX.SelectedIndex]);
                }
                if (cbProtoAttributeY.SelectedIndex >= 0)
                {
                    chartMain.ChartAreas[0].AxisY.Title = StringEnum.GetStringValue(ClassKeyList[cbProtoAttributeY.SelectedIndex]);
                }
            }
            chartMain.Invalidate();
        }
예제 #9
0
        public RuleParser()
        {
            PercentComplete        = 0.0;
            current_buy_functions  = new List <Fn>();
            current_sell_functions = new List <Fn>();

            foreach (Variable var in RuleParserInputs.VarList)
            {
                VariablesTable.Add(StringEnum.GetStringValue(var), var);
            }
        }
예제 #10
0
        public RuleParser()
        {
            PercentComplete        = 0.0;
            current_buy_functions  = new List <Fn>();
            current_sell_functions = new List <Fn>();
            buy_history            = new List <bool>();
            sell_history           = new List <bool>();

            foreach (Variable var in RuleParserInputs.VarList.Concat(RuleParserInputs.VarList2))
            {
                KeysTable.Add(StringEnum.GetStringValue(var), var);
            }
        }
예제 #11
0
        private void InitializePrivateGlobals()
        {
            dataSet                         = null;
            statsMarketData                 = null;
            lastDisplayedCorrelation        = -1;
            lastSelectedTab                 = 0;
            CorrelationTableSortInstruction = new List <string>();
            AllTransformApplied             = false;
            DataIsValid                     = 0;

            for (int i = 0; i < TransformTList.Length; i++)
            {
                this.tsComboTransformation.Items.Add(StringEnum.GetStringValue(TransformTList[i]));
            }
        }
예제 #12
0
        /*****************************************************************************
        *  FUNCTION:       loadDataManagerConfig
        *  Description:
        *  Parameters:     None
        *****************************************************************************/
        private void loadDataManagerConfig()
        {
            XmlDocument configFile       = new XmlDocument();
            string      application_path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            string      config_path      = Path.Combine(application_path, MyMarketAnalyzer.Properties.Resources.DataManagerConfigPath);

            config_path = new Uri(config_path).LocalPath;

            string      market_name = "", market_query = "", market_smlid = "";
            string      option_id, option_name;
            XmlNode     marketNode;
            XmlNodeList nodeList;

            List <t_ActiveMarket> tempMktList;

            configFile.Load(config_path);

            foreach (MarketRegion mkt in SelectableMarketRegions)
            {
                market_name  = StringEnum.GetStringValue(mkt);
                market_query = string.Format("Datamanager/Live/Markets/Data/Market[@name='{0}']", market_name);
                nodeList     = configFile.SelectNodes(market_query);

                if (nodeList.Count > 0)
                {
                    marketNode   = nodeList[0];
                    tempMktList  = new List <t_ActiveMarket>();
                    market_smlid = marketNode.Attributes.GetNamedItem("smlID").InnerText;

                    nodeList = marketNode.SelectNodes("option");
                    foreach (XmlNode i_mkt in nodeList)
                    {
                        option_id   = i_mkt.Attributes.GetNamedItem("id").InnerText;
                        option_name = i_mkt.InnerText;
                        tempMktList.Add(new t_ActiveMarket(market_smlid, DEFAULT_SID, option_id, option_name));
                    }

                    this.ListOfMarkets[SelectableMarketRegions.IndexOf(mkt)] = tempMktList;
                }
            }
        }
예제 #13
0
        /*****************************************************************************
        *  FUNCTION:       RunAnalysis
        *  Description:
        *  Parameters:     None
        *****************************************************************************/
        public AnalysisResult RunAnalysis()
        {
            int    i;
            bool   buy, sell;
            string str_expression, str_evaluated_rule;
            double gain_loss = 0.0, cash = inPrincipalAmt, investments = 0.0, transaction_amt = 0.0;
            int    units = 0, units_held = 0, total_transactions = 0;

            String[]       buy_conditions = inBuyRule.Split(RuleParserInputs.Operators, StringSplitOptions.RemoveEmptyEntries);
            String[]       sell_conditions = inSellRule.Split(RuleParserInputs.Operators, StringSplitOptions.RemoveEmptyEntries);
            AnalysisResult analysis_result = new AnalysisResult();

            PercentComplete = 0.0;

            //Get the list of functions passed in the current Buy and Sell rules
            //(so that we don't have to itterate again for each data point)
            current_buy_functions.Clear();
            current_sell_functions.Clear();
            foreach (Fn func in RuleParserInputs.Fns)
            {
                foreach (String buy_cond in buy_conditions)
                {
                    if (buy_cond.Contains(StringEnum.GetStringValue(func)))
                    {
                        current_buy_functions.Add(func);
                    }
                }
                foreach (String sell_cond in sell_conditions)
                {
                    if (sell_cond.Contains(StringEnum.GetStringValue(func)))
                    {
                        current_sell_functions.Add(func);
                    }
                }
            }

            //ex. ((MACD_DIFF > 0) AND (P < AVG[P][-5..0]))

            //For every day in data
            for (i = 0; i < inEquity.HistoricalPriceDate.Count; i++)
            {
                //Initialize analysis result values
                analysis_result.cash_totals.Add(0.0);
                analysis_result.investments_totals.Add(0.0);
                analysis_result.net_change_daily.Add(0.0);
                analysis_result.units_change_daily.Add(0);

                //Evaluate the given historical data point against each of the buy rules
                buy = false;
                str_evaluated_rule = inBuyRule;

                //Get the number of units to buy
                units = GetNumberOfUnits(str_evaluated_rule, out str_evaluated_rule, inEquity.HistoricalPrice[i], cash);

                //Parse each of the individual conditional expressions and evaluate the overall rule
                foreach (String buy_cond in buy_conditions)
                {
                    str_expression     = Parse(buy_cond, inEquity, i, current_buy_functions);
                    str_evaluated_rule = str_evaluated_rule.Replace(buy_cond, str_expression);
                }
                buy = Evaluate(str_evaluated_rule);

                //Update holdings if the buy rule evaluates to True
                if (buy)
                {
                    transaction_amt = inEquity.HistoricalPrice[i] * units;
                    if (cash >= (transaction_amt))
                    {
                        units_held += units;
                        cash       -= transaction_amt;
                        investments = (inEquity.HistoricalPrice[i] * units_held);
                        total_transactions++;
                    }
                }

                //Evaluate the given historical data point against each of the sell rules
                sell = false;
                str_evaluated_rule = inSellRule;

                //Get the number of units to sell
                units = GetNumberOfUnits(str_evaluated_rule, out str_evaluated_rule, 1.0, investments);

                foreach (String sell_cond in sell_conditions)
                {
                    str_expression     = Parse(sell_cond, inEquity, i, current_sell_functions);
                    str_evaluated_rule = str_evaluated_rule.Replace(sell_cond, str_expression);
                }
                sell = Evaluate(str_evaluated_rule);

                if (sell)
                {
                    transaction_amt = inEquity.HistoricalPrice[i] * units;
                    if (investments >= transaction_amt)
                    {
                        units_held -= units;
                        cash       += transaction_amt;
                        investments = (inEquity.HistoricalPrice[i] * units_held);
                        total_transactions++;
                        units = 0;
                    }
                }

                //update Analyis result structure
                analysis_result.cash_totals[i]        = cash;
                analysis_result.investments_totals[i] = investments;
                analysis_result.net_change_daily[i]   = (cash + investments);
                analysis_result.units_change_daily[i] = units_held;
                analysis_result.dates_from_to         = new Tuple <DateTime, DateTime>(inEquity.HistoricalPriceDate[0],
                                                                                       inEquity.HistoricalPriceDate[inEquity.HistoricalPriceDate.Count - 1]);

                if (i > 0)
                {
                    analysis_result.net_change_daily[i] -= (analysis_result.cash_totals[i - 1] +
                                                            analysis_result.investments_totals[i - 1]);

                    analysis_result.units_change_daily[i] -= analysis_result.units_change_daily[i - 1];
                }


                //Update progress
                PercentComplete = ((double)(i + 1) / (double)inEquity.HistoricalPriceDate.Count);
            }

            PercentComplete = 1.0;

            gain_loss = (cash + investments) - inPrincipalAmt;
            analysis_result.net_change = gain_loss;

            return(analysis_result);
        }
예제 #14
0
        /*****************************************************************************
        *  FUNCTION:       Parse
        *  Description:    Replaces a primitive expression with corresponding numeric values
        *                  to enable evaluation.
        *
        *                  Ex. (P < AVG[P][-5..0])
        *  Parameters:
        *
        *****************************************************************************/
        private String Parse(String pExpression, Equity pEqIn, int pIndex, List <Fn> pFNs)
        {
            string parameter, str_expression, fn_str;
            double parameter_value = 0.0;

            string[] split_str;
            int      index1, index2;
            Variable in_param;

            str_expression = pExpression;
            //For each function in the expression being parsed
            foreach (Fn func in pFNs)
            {
                fn_str = "";
                if (pExpression.Contains(StringEnum.GetStringValue(func)))
                {
                    //Get the substring containing only the logical expression for this function
                    index1 = pExpression.IndexOf(StringEnum.GetStringValue(func));
                    index2 = pExpression.IndexOf("]", index1);

                    if (pExpression.Length > index2 && pExpression.ToCharArray()[index2 + 1] == '[')
                    {
                        index2 = pExpression.IndexOf("]", index2 + 1);
                    }

                    fn_str = pExpression.Substring(index1, index2 - index1 + 1);

                    try
                    {
                        //Evaluate the function and replace the substring in the original parent expression with the value
                        str_expression = str_expression.Replace(fn_str.Trim(), GetFunction(func, pEqIn, fn_str, pIndex).ToString());
                    }
                    catch (IndexOutOfRangeException)
                    {
                        //The index will be out of range even for a valid command if the function operates on past data that
                        // isn't available at the start of a series.
                        //
                        // Ex. AVG[P][-5..0] --> at the start of the price data series, there aren't 5 previous data points available
                        //     to calculate an average on.
                        //
                        // In this case, just return false to allow the rest of the command to be processed.
                        return("false");
                    }
                    catch (Exception)
                    {
                        errorIndex[0] = index1;
                        errorIndex[1] = index2;
                        return("ERROR");
                    }
                }
            }

            split_str = str_expression.Split(RuleParserInputs.Comparators, StringSplitOptions.RemoveEmptyEntries);

            foreach (string exp_part in split_str)
            {
                parameter = CleanExpression(exp_part.Trim()).Replace("NOT", "");

                if (Helpers.ValidateNumeric(parameter) == false)
                {
                    in_param = GetParameterType(parameter);

                    try
                    {
                        //If the data to be analyzed is one of the MACD signals, ensure the passed index is valid
                        if (in_param == Variable.MACD_DIFF || in_param == Variable.MACD_SIG)
                        {
                            if (pIndex > (pEqIn.HistoricalPrice.Count() - pEqIn.MACD_C.Count()))
                            {
                                parameter_value = GetParameter(pEqIn, parameter, pIndex);
                                str_expression  = str_expression.ReplaceFirstOccurrence(parameter, parameter_value.ToString());
                            }
                        }
                        else
                        {
                            parameter_value = GetParameter(pEqIn, parameter, pIndex);
                            str_expression  = str_expression.ReplaceFirstOccurrence(parameter, parameter_value.ToString());
                        }
                    }
                    catch (IndexOutOfRangeException)
                    {
                        return("false");
                    }
                    catch (Exception)
                    {
                        errorIndex[0] = 0;
                        errorIndex[1] = 0;
                        return("ERROR");
                    }
                }
            }

            return(str_expression);
        }
예제 #15
0
        private int ExpressionEndIndex(string pRuleString, int pFromIndex)
        {
            int    nesting_level = 0, param_level = 0;
            int    index1  = 0;
            string tempStr = "";
            bool   isfound = false;

            //find the end of the expression
            nesting_level = 0;
            param_level   = 0;
            isfound       = false;
            index1        = pFromIndex;

            while (index1 < pRuleString.Length)
            {
                switch (pRuleString[index1])
                {
                case '(':
                    nesting_level++;
                    break;

                case ')':
                    nesting_level--;
                    break;

                case '[':
                    param_level++;
                    break;

                case ']':
                    param_level--;
                    break;

                default:
                    break;
                }
                tempStr = pRuleString.SubWord(index1);

                try
                {
                    double.Parse(tempStr);
                    isfound = true;
                    index1 += tempStr.Length;
                }
                catch
                {
                    if (RuleParserInputs.Fns.Where(a => StringEnum.GetStringValue(a) == tempStr).Count() > 0)
                    {
                        isfound = true;
                        index1 += tempStr.Length - 1;
                    }
                    else if (RuleParserInputs.VarList.Where(a => StringEnum.GetStringValue(a) == tempStr).Count() > 0 &&
                             (param_level == 0))
                    {
                        isfound = true;
                        index1 += tempStr.Length - 1;
                    }
                }

                if (isfound && (param_level == 0) && (nesting_level == 0))
                {
                    //look ahead to the next character in case a valid fn or param string is found
                    // to ensure the whole parameter is taken
                    if (index1 < (pRuleString.Length - 1) && pRuleString[index1 + 1] == '[')
                    {
                        param_level++;
                    }
                    else
                    {
                        break;
                    }
                }

                index1++;
            }

            return(index1);
        }
예제 #16
0
        private String PreprocessRule(String pRuleString)
        {
            string subexpression = "", returnString = "";
            int    index1 = 0, index2 = 0;
            string indexStr = "", newRule = "";

            returnString = pRuleString;
            returnString = (new Regex("\\s+")).Replace(returnString, " ");

            //Find all instances of the "becomes" keyword and create the edge-detection string
            foreach (int index in pRuleString.AllIndexesOf("becomes"))
            {
                index1 = ExpressionStartIndex(pRuleString, index - 1);
                index2 = ExpressionEndIndex(pRuleString, index + 7);

                subexpression = pRuleString.Substring(index1, index2 - index1);

                //Replace all existing index specifiers with ones decremented by 1
                index1  = subexpression.IndexOf('[');
                newRule = subexpression;
                while (index1 >= 0)
                {
                    index2 = subexpression.IndexOf(']', index1);

                    if (index2 > index1)
                    {
                        indexStr = subexpression.Substring(index1 + 1, index2 - index1 - 1);
                    }
                    else
                    {
                        break;
                    }

                    //replace the indexStr with indexes decremented by 1
                    foreach (Match si in Regex.Matches(indexStr, "[-]*[0-9]+"))
                    {
                        indexStr = indexStr.ReplaceFirstOccurrence(si.Value, (int.Parse(si.Value) - 1).ToString());
                    }

                    newRule = newRule.ReplaceFirstOccurrence(subexpression.Substring(index1 + 1, index2 - index1 - 1), indexStr);
                    index1  = subexpression.IndexOf('[', index2);
                }

                //For variables used without an index specifier (indicating current data), need to add [-1] specifier
                foreach (Variable vari in RuleParserInputs.VarList)
                {
                    MatchCollection mc = Regex.Matches(newRule, "\\b" + StringEnum.GetStringValue(vari) + "\\b");
                    int             i = 0, offset = 0;

                    while (i < mc.Count)
                    {
                        index1 = mc[i++].Index + offset;
                        index2 = index1 + StringEnum.GetStringValue(vari).Length;
                        if (newRule[index2] != '[' && newRule[index2] != ']')
                        {
                            newRule = newRule.Insert(index2, "[-1]");
                            offset += 4;
                        }
                    }
                }

                //Create the new subexpression, replacing "becomes" with the same rule using 'previous' indexes
                newRule = "(" + subexpression.Replace("becomes", "") + " AND NOT(" + newRule.Replace("becomes", "") + "))";
                newRule = newRule.Replace("  ", " ").Trim();

                returnString = returnString.Replace(subexpression, newRule);
                returnString = (new Regex("\\s+")).Replace(returnString, " ");
            }

            return(returnString);
        }