0

我很难理解 NCalc,我有几个问题。

1) 如果我有一个像“if(CLOSE<2.3,ROC(OPEN),HIGH)”这样的表达式并且 ROC 是一个自定义函数。在评估条件“CLOSE<2.3”时,“ROC(OPEN)”的结果是否可用?

2)我如何覆盖“如果”语句?对于下面的情况,我想对“listOpen”中的每个元素进行条件检查。如果条件评估为 TRUE,则我需要从“listROC”返回条件评估为 true 的索引处的值,否则从 listHigh 返回相同索引处的值。

例子 :

List<double> listResult =  new List<double>();
for(int index = 0; index< listClose.count;index++)
{
    if(listClose[index]<2.3)
         listResult.Add(listROC[index]);
    else
         listResult.Add(listHigh[index]);

}

return listResult;

这是我试图评估表达式的示例代码。我坚持覆盖/定义自定义 if 语句。

    private List<double> listOpen = new List<double>();
    private List<double> listClose = new List<double>();
    private List<double> listHigh = new List<double>();
    public void PrepareData()
    {
        for (int index = 0; index < 10; index++)
        {
            Random rnd = new Random();
            double open = rnd.NextDouble() * (2.5 - 2.0) + 2.0;
            listOpen.Add(open);
            double close = rnd.NextDouble() * (2.5 - 2.0) + 2.0;
            listClose.Add(close);
            double high = rnd.NextDouble() * (2.5 - 2.0) + 2.0;
            listHigh.Add(high);

        }
    }
    private void EvaluateExpression()
    {
        PrepareData();

        Expression ex = new Expression("if(CLOSE<2.3,ROC(OPEN),HIGH)");
        ex.EvaluateFunction += delegate(string name, FunctionArgs args)
        {
            if (name == "ROC")
            {
                List<double> listROC = new List<double>();
                string argument = args.Parameters[0].Evaluate().ToString();
                List<double> listParam = new List<double>();
                switch (argument)
                {
                    case "OPEN":
                        listParam = listOpen;
                        break;
                    case "CLOSE":
                        listParam = listClose;
                        break;
                    case "HIGH":
                        listParam = listHigh;
                        break;
                }
                foreach (double dbl in listParam)
                {
                    double result = dbl * 2;
                    listROC.Add(result);
                }
                args.Result = listROC;
            }
            if (name == "if")
            {
               //Override the if function
            }
        };

        object ob = ex.Evaluate();
    }

任何帮助深表感谢。

4

2 回答 2

0

我的理解是:

1) 表达式被一起解析,然后根据深度进行评估。所以if谓词CLOSE<2.3将被评估为真,然后如果为真ROC(OPEN)将被评估。如果您在声明参数之前尝试使用参数,这将是一个问题 - 就像您编写自定义的情况一样MAP(arg_array, callback([i])),它会解析callback([i])预期参数从评估开始时就[i]存在。

2) 只要​​您处理函数名称并设置结果,它就应该覆盖任何可能发生的本机处理。我犯了一个错误,即创建一个总是设置结果的便利处理程序(或者如果它无法识别该函数则抛出异常),这会在无法识别的if语句上抛出异常。IF您也可以始终使用(区分大小写)定义自己的 if 语句。


但我认为你的问题是CLOSE并且应该是静态值,因此OPEN应该像字符串一样转义。或声明为参数并进行相应处理。https://ncalc.codeplex.com/wikipage?title=parameters'CLOSE''OPEN'

于 2015-01-28T15:09:43.537 回答
0

无法弄清楚你想要达到的目标,也许如果你能解释更多,就能更好地帮助你。你不能覆盖“if”,如果你不希望行为像内置的那样在表达式中使用其他词,如 IF() 或 Filter()

于 2012-04-19T04:44:54.103 回答