예제 #1
0
        public static bool CheckFunction(string function, out string error, IEnumerable <string> validParamNames)
        {
            if (string.IsNullOrEmpty(function))
            {
                error = "Функция не может быть пустой";
                return(false);
            }
            ExpressionResolver resv;

            try
            {
                resv = new ExpressionResolver(function);
            }
            catch
            {
                error = "Функция не распознана";
                return(false);
            }
            var lackVars =
                resv.GetVariableNames()
                .Where(n => !validParamNames.Any(p => p.Equals(n, StringComparison.OrdinalIgnoreCase)));

            error = string.Join(", ", lackVars);
            if (string.IsNullOrEmpty(error))
            {
                return(true);
            }
            error = "Переменные " + error;
            return(false);
        }
        public static ExpressionResolver CheckFunction(string formula, out string error)
        {
            error = string.Empty;

            ExpressionResolver resolver;
            try
            {
                resolver = new ExpressionResolver(formula);
            }
            catch (Exception ex)
            {
                error = Resource.ErrorMessageInFunction + " '" + formula + "': " + ex.Message;
                return null;
            }

            var resolverVars = resolver.GetVariableNames();
            if (resolverVars.Any(v => !formulaProperties.ContainsKey(v)))
            {
                error = Resource.ErrorMessageUnknownVariables + ": " +
                           string.Join(", ", resolverVars.Where(v => !formulaProperties.ContainsKey(v)));
                return null;
            }

            return resolver;
        }
예제 #3
0
 public void BracketDisparity()
 {
     var resolver = new ExpressionResolver("(a + (b) * c");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 1);
     vars.Add("b", 1);
     vars.Add("c", 1);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsFalse(ret, resolver.Formula);
 }
예제 #4
0
 public void Logarithmic()
 {
     var resolver = new ExpressionResolver("2.71 ^ ln(a) + 10 ^ lg(b)");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 2);
     vars.Add("b", 3);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(Math.Pow(2.71, Math.Log(vars["a"])) + Math.Pow(10, Math.Log10(vars["b"])), result, resolver.Formula);
 }
예제 #5
0
 public void Logical()
 {
     var resolver = new ExpressionResolver("a & b | c");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 1);
     vars.Add("b", 0);
     vars.Add("c", 1);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(1, result, resolver.Formula);
 }
예제 #6
0
 public void Comparison()
 {
     var resolver = new ExpressionResolver("a > b = c < d");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 1);
     vars.Add("b", 2);
     vars.Add("c", 4);
     vars.Add("d", 3);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     var expected = vars["a"] > vars["b"] == vars["c"] < vars["d"];
     Assert.AreEqual(expected ? 1 : 0, result, resolver.Formula);
 }
예제 #7
0
        public IndexCalculator(string indexFormula)
        {
            try
            {
                resolver = new ExpressionResolver(indexFormula);
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("Ошибка парсинга формулы \"{0}\" в IndexCalculator: {1}",
                    indexFormula, ex);
                resolver = null;
                return;
            }

            formulaVariableNames = resolver.GetVariableNames();
        }
예제 #8
0
 public void AdditionAndVarDisparity()
 {
     var resolver = new ExpressionResolver("a + b + c");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 1);
     vars.Add("b", 2);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsFalse(ret, resolver.Formula + " lack of args");
     vars.Add("c", 3);
     ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(vars["a"] + vars["b"] + vars["c"], result, resolver.Formula);
     vars.Add("d", 4);
     ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula + " excess of args");
 }
예제 #9
0
        public static double ToExpressionResult(this string expression, double defaultValue)
        {
            ExpressionResolver resv;

            try
            {
                resv = new ExpressionResolver(expression);
            }
            catch
            {
                return(defaultValue);
            }

            try
            {
                double rst;
                return(resv.Calculate(new Dictionary <string, double>(), out rst) ? rst : defaultValue);
            }
            catch
            {
                return(defaultValue);
            }
        }
예제 #10
0
        private void CheckFormulaParams()
        {
            formulaParams = resolver.GetVariableNames();
            var errorPtrs = new List<string>();
            var tickers = DalSpot.Instance.GetTickerNames();

            foreach (var ptr in formulaParams)
            {
                if (ExpressionResolverLiveParams.CheckParamName(ptr)) continue;
                if (tickers.Any(t => t.Equals(ptr, StringComparison.OrdinalIgnoreCase)))
                    continue;
                errorPtrs.Add(ptr);
            }

            if (errorPtrs.Count == 0) return;
            FormulaError = "Некорректные параметры: " + string.Join(", ", errorPtrs);
            formulaParams = null;
            resolver = null;
        }
예제 #11
0
        public static string GetFormulaHighlightedHtml(string formula)
        {
            const string header =
                "<html>\n<head>\n" +
                "<meta charset=\"utf-8\" />\n" +
                "<style type=\"text/css\">\n" +
                "    div.code { font-family: 'Courier New'; } \n" +
                " </style>\n" +
                "</head>\n" +
                "<body>\n" +
                "  <div class=\"code\">\n";

            const string footer = "  </div>\n</body>\n</html>";

            if (string.IsNullOrEmpty(formula))
                return header + footer;

            // для каждой переменной формулы создать гиперссылку вида
            // <a href="javascript:void(0);" title="Доход
            //Суммарная доходность по счету, %">P</a>+1)*2.5)
            // именно так!

            var resolver = new ExpressionResolver(formula);
            var varNames = resolver.GetVariableNames().OrderByDescending(v => v.Length).ToList();
            var tokens = new List<ExpressionToken>();
            foreach (var varName in varNames)
            {
                var pos = -1;
                while (true)
                {
                    pos = formula.IndexOf(varName, pos + 1, StringComparison.InvariantCultureIgnoreCase);
                    if (pos < 0) break;

                    if (tokens.Any(t => t.pos <= pos && (t.pos + t.len) >= pos)) continue;

                    tokens.Add(new ExpressionToken
                        {
                            pos = pos,
                            name = varName,
                            len = varName.Length,
                            replacement = MakeExpressionParameterHyperlink(varName).Replace("<", "#-").Replace(">", "#+")
                        });
                }
            }

            foreach (var token in tokens)
            {
                var tokenPos = token.pos;
                var deltaLen = token.replacement.Length - token.len;
                formula = formula.Substring(0, token.pos) + token.replacement + formula.Substring(token.pos + token.len);
                foreach (var t in tokens.Where(x => x.pos > tokenPos))
                    t.pos += deltaLen;
            }

            formula = formula.Replace("#-", "<").Replace("#+", ">");
            return formula;
        }
예제 #12
0
        public static bool ParseSimpleFormula(string expression,
                                              out List<Cortege3<PerformerStatField, ExpressionOperator, double>> filters,
                                              out PerformerStatField sortField)
        {
            ExpressionResolver resv;
            filters = new List<Cortege3<PerformerStatField, ExpressionOperator, double>>();
            sortField = null;
            try
            {
                resv = new ExpressionResolver(expression);
            }
            catch
            {
                return false;
            }

            // одно из поддеревьев должно быть листом - PerformerStatField
            if (resv.rootOperand == null) return false;
            if (resv.rootOperand.OperandLeft == null &&
                resv.rootOperand.OperandRight == null)
            {
                // частный случай - формула вида "1", "AYP" ...
                var sortVal = resv.rootOperand.IsConstant
                    ? resv.rootOperand.ConstantValue.ToStringUniform() : resv.rootOperand.VariableName;
                sortField = fields.FirstOrDefault(f => f.ExpressionParamName != null &&
                    f.ExpressionParamName.Equals(sortVal, StringComparison.OrdinalIgnoreCase));
                return sortField != null;
            }

            if (resv.rootOperand.OperandLeft == null ||
                resv.rootOperand.OperandRight == null)
            {
                filters = null;
                return false;
            }

            var root = resv.rootOperand.OperandRight;
            var sorter = resv.rootOperand.OperandLeft;
            if (!sorter.IsVariable)
            {
                sorter = resv.rootOperand.OperandRight;
                root = resv.rootOperand.OperandLeft;
            }
            if (!sorter.IsVariable)
            {
                filters = null;
                return false;
            }
            sortField = fields.FirstOrDefault(f => f.ExpressionParamName != null &&
                f.ExpressionParamName.Equals(sorter.VariableName, StringComparison.OrdinalIgnoreCase));
            if (sortField == null)
            {
                filters = null;
                return false;
            }

            // разобрать другое поддерево (root)
            if (root.IsConstant || root.IsVariable)
            {
                filters = null;
                sortField = null;
                return false;
            }
            return ParseSimpleFormulaBranch(root, filters);
        }
예제 #13
0
 public void Trigonometrical()
 {
     var resolver = new ExpressionResolver("sin(a) / cos(a) - tan(a)");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 0.3);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(Math.Sin(vars["a"]) / Math.Cos(vars["a"]) - Math.Tan(vars["a"]), result, resolver.Formula);
 }
예제 #14
0
        public void TestIndexFunction()
        {
            var resolver = new ExpressionResolver("(close-close#40)*2");
            double result;
            var vars = new Dictionary<string, double>
                {
                    { "close", 1.35 },
                    { "close#40", 1.34 }
                };
            var ret = resolver.Calculate(vars, out result);
            Assert.IsTrue(ret, resolver.Formula);

            const double resultRight = (1.35 - 1.34)*2;
            var delta = Math.Abs(resultRight - result);
            Assert.Less(delta, 0.000001, "IndexFunction is calculated right");
        }
예제 #15
0
 public void SubtractionNegationAndSpacing()
 {
     var resolver = new ExpressionResolver("-a -  -b - c");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 1);
     vars.Add("b", 1);
     vars.Add("c", 1);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(-vars["a"] - -vars["b"] - vars["c"], result, resolver.Formula);
 }
예제 #16
0
 public void SignAndNullReplacing()
 {
     var resolver = new ExpressionResolver("sign(a ?? 5)");
     double result;
     var vars = new Dictionary<string, double> {{"a", 0}};
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(Math.Sign(vars["a"] == 0 ? 5 : vars["a"]), result, resolver.Formula);
     vars["a"] = -1;
     ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(Math.Sign(vars["a"] == 0 ? 5 : vars["a"]), result, resolver.Formula);
 }
예제 #17
0
 public void MultiplicationAndDivision()
 {
     var resolver = new ExpressionResolver("a * b / c");
     double result;
     var vars = new Dictionary<string, double>();
     vars.Add("a", 3);
     vars.Add("b", 4);
     vars.Add("c", 6);
     var ret = resolver.Calculate(vars, out result);
     Assert.IsTrue(ret, resolver.Formula);
     Assert.AreEqual(vars["a"] * vars["b"] / vars["c"], result, resolver.Formula);
 }
예제 #18
0
 private bool CheckFormula()
 {
     Formula = formulaComboBox.Text;
     try
     {
         var resolver = new ExpressionResolver(Formula.ToLower());
         //string absentVars = ""
         string excessVars = "";
         var vars = resolver.GetVariableNames();
         var neededArgs = NewsRobot.formulaArguments.Select(argAndComm => argAndComm.Key.ToLower());
         /*foreach (var argument in neededArgs)
             if (!vars.Contains(argument))
             {
                 if (!string.IsNullOrEmpty(absentVars))
                     absentVars += ", ";
                 absentVars += argument;
             }*/
         foreach (var argument in vars)
         {
             if(!neededArgs.Contains(argument))
             {
                 if (!string.IsNullOrEmpty(excessVars))
                     excessVars += ", ";
                 excessVars += argument;
             }
         }
         if (/*!string.IsNullOrEmpty(absentVars) || */!string.IsNullOrEmpty(excessVars))
         {
             MessageBox.Show(this,
                             /*(!string.IsNullOrEmpty(absentVars)
                                  ? "В формуле отсутствуют необходимые параметры: " + absentVars + "\n"
                                  : "") +*/
                             (!string.IsNullOrEmpty(excessVars)
                                  ? "В формуле присутствуют лишние параметры: " + excessVars
                                  : ""), "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
             return false;
         }
     }
     catch (Exception)
     {
         MessageBox.Show(this, "Синтаксическая ошибка в формуле", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
         return false;
     }
     return true;
 }
예제 #19
0
 private void CalcButtonClick(object sender, EventArgs e)
 {
     if (!CheckFormula())
     {
         resultLabel.Text = "Ошибка в формуле";
         return;
     }
     var resolver = new ExpressionResolver(Formula.ToLower());
     var values = new Dictionary<string, double>();
     foreach (var row in argumentsFastGrid.rows)
     {
         var arg = (FormulaArgument) row.ValueObject;
         values.Add(arg.Name.ToLower(), (double)arg.Value);
     }
     double result;
     var resultFlag = resolver.Calculate(values, out result);
     if (!resultFlag)
     {
         resultLabel.Text = "Ошибка в расчете по формуле";
         return;
     }
     resultLabel.Text = result == 0 ? "Нет входа в рынок" : "Вход в рынок";
 }
예제 #20
0
 public override void Initialize(RobotContext context, CurrentProtectedContext protectedContext)
 {
     var cfgFileName = Assembly.GetAssembly(GetType()).Location + ".xml";
     string error;
     newsSettings = NewsSettings.LoadNewsSettings(cfgFileName, out error);
     if (error != null)
         pendingLogMessages.Add(error);
     currencySettings = CurrencySettings.LoadCurrencySettings(cfgFileName, out error);
     if (error != null)
         pendingLogMessages.Add(error);
     if(string.IsNullOrEmpty(Formula))
         pendingLogMessages.Add("формула не задана");
     try
     {
         expressionResolver = new ExpressionResolver(Formula.ToLower());
     }
     catch (Exception)
     {
         pendingLogMessages.Add("ошибка в формуле");
     }
     base.Initialize(context, protectedContext);
 }
        public List<PerformerStat> GetAllPerformersWithCriteria(bool managersOnly, string criteria, int count, bool ascending,
            float? marginScore, int serviceTypeMask)
        {
            // данные не готовы к работе
            if (!cacheUpdated)
            {
                Logger.Info("GetAllPerformersWithCriteria - данные не готовы");
                return new List<PerformerStat>();
            }

            ExpressionResolver resv;
            try
            {
                resv = new ExpressionResolver(criteria);
            }
            catch
            {
                resv = null;
            }

            var result = new List<PerformerStat>();
            var startTime = DateTime.Now;
            foreach (var performer in dicPerformers.ReceiveAllData())
            {
                if (managersOnly && performer.Value.Statistics.Service == 0) continue;
                var performerStat = performer.Value.Statistics;
                if (resv != null)
                    performerStat.UserScore = (float) PerformerCriteriaFunction.Calculate(resv, performerStat);
                else
                    performerStat.UserScore = performerStat.Profit;
                // отсеять тех, кто не удовлетворяет условию
                if (marginScore.HasValue)
                    //if (performerStat.UserScore.AreSame(marginScore.Value, 0.0001f)) continue;
                    if ((performerStat.UserScore <= marginScore.Value && !ascending) ||
                        (performerStat.UserScore >= marginScore.Value && ascending))
                        continue;
                if (serviceTypeMask != 0)
                {
                    if ((serviceTypeMask & 1) != 0)
                        if(performerStat.ServiceType != (int) PaidServiceType.Signals)
                            continue;
                    if ((serviceTypeMask & 2) != 0)
                        if (performerStat.ServiceType != (int) PaidServiceType.PAMM)
                            continue;
                }
                result.Add(performerStat);
            }

            // отсортировать и отобрать count результатов
            var total = result.Count;
            result.Sort(ComparePerformerStats);
            if (!ascending)
                result.Reverse();
            if (result.Count > count)
                result = result.GetRange(0, count);

            Logger.InfoFormat("GetAllPerformersWithCriteria (managersOnly={0}, criteria={1}, count={2}, margin={3})" +
                " - записей: {4}, время вычислений: {5} мс",
                managersOnly,
                criteria + (ascending ? "[asc]" : "[desc]"),
                count,
                marginScore,
                total,
                DateTime.Now.Subtract(startTime).TotalMilliseconds);

            return result.ToList();
        }
예제 #22
0
        public void LogicalExpression()
        {
            var expressionResult = new Dictionary<string, Cortege2<Dictionary<string, double>, double>>
                {
                    {
                        "~a", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"a", 1}
                            }, 0)
                    },
                    {
                        "a&~b", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"a", 1},
                                {"b", 0}
                            }, 1)
                    },
                    {
                        "~c!=~b", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"b", 1},
                                {"c", 0}
                            }, 1)
                    },
                    {
                        "(a=~b)&({c!=a}||~c)", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"a", 1},
                                {"b", 0},
                                {"c", 1} // not 0 therefore true
                            }, 0)
                    },
                    {
                        "(a = ~b) & ({c != a} || ~c)", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"a", 1},
                                {"b", 0},
                                {"c", 0} // not 0 therefore true
                            }, 1)
                    },
                    {
                        "(_pi&1)=(b&b)", new Cortege2<Dictionary<string, double>, double>(new Dictionary<string, double>
                            {
                                {"b", 1},
                            }, 1)
                    }
                };

            foreach (var exRst in expressionResult)
            {
                var expression = exRst.Key;

                ExpressionResolver resolver;
                try
                {
                    resolver = new ExpressionResolver(expression);
                }
                catch (Exception ex)
                {
                    Assert.Fail("\"" + expression + "\" не распознано: " + ex);
                    continue;
                }

                var vars = exRst.Value.a;
                var expected = exRst.Value.b;
                try
                {
                    double result;
                    var rst = resolver.Calculate(vars, out result);
                    Assert.IsTrue(rst, expression + " is calculated");
                    Assert.AreEqual(expected, result, expression + " should be equal " + expected);
                }
                catch (Exception ex)
                {
                    Assert.Fail(expression + ": exception while calculate: " + ex);
                }
            }
        }
예제 #23
0
        public override void Initialize(BacktestServerProxy.RobotContext grobotContext)
        {
            base.Initialize(grobotContext);
            // проверка настроек графиков
            if (Graphics.Count == 0)
            {
                Logger.DebugFormat("OscillatorBasedRobot: настройки графиков не заданы");
                return;
            }
            if (Graphics.Count > 1)
            {
                Logger.DebugFormat("OscillatorBasedRobot: настройки графиков должны описывать один тикер / один ТФ");
                return;
            }
            ticker = Graphics[0].a;

            try
            {
                formulaResolver = new ExpressionResolver(indexFormula);
                formulaVariableNames = formulaResolver.GetVariableNames();
                lastBids = new Dictionary<string, float>();
                lastIndicies = new RestrictedQueue<float>(CandlesInIndexHistory);
                candles = new RestrictedQueue<CandleData>(CandlesInIndexHistory);
                packer = new CandlePacker(Graphics[0].b);
                indexPeaks = new List<Cortege3<float, int, float>>();
                tickerNames = DalSpot.Instance.GetTickerNames();
                randomGener = new Random(DateTime.Now.Millisecond);
                lastBidLists = new Dictionary<string, RestrictedQueue<float>>();
                // по каждой валютной паре найти макс. количество отсчетов (из формулы индекса)
                InitLastBidLists();
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("OscillatorBasedRobot: ошибка парсинга выражения \"{0}\": {1}",
                                   indexFormula, ex);
                formulaResolver = null;
            }
        }
예제 #24
0
 public FunctionCheckForm(string function)
     : this()
 {
     lblFormula.Text = function;
     resolver = new ExpressionResolver(function);
 }
예제 #25
0
 public static bool CheckFunction(string function, out string error, IEnumerable<string> validParamNames)
 {
     if (string.IsNullOrEmpty(function))
     {
         error = "Функция не может быть пустой";
         return false;
     }
     ExpressionResolver resv;
     try
     {
         resv = new ExpressionResolver(function);
     }
     catch
     {
         error = "Функция не распознана";
         return false;
     }
     var lackVars =
         resv.GetVariableNames()
             .Where(n => !validParamNames.Any(p => p.Equals(n, StringComparison.OrdinalIgnoreCase)));
     error = string.Join(", ", lackVars);
     if (string.IsNullOrEmpty(error)) return true;
     error = "Переменные " + error;
     return false;
 }