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; }
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); }
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); }
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); }
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); }
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(); }
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"); }
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); } }
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; }
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; }
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); }
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); }
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"); }
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); }
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); }
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); }
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; }
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 ? "Нет входа в рынок" : "Вход в рынок"; }
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(); }
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); } } }
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; } }
public FunctionCheckForm(string function) : this() { lblFormula.Text = function; resolver = new ExpressionResolver(function); }
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; }