0

NCalc を理解するのに苦労しており、いくつか質問があります。

1) 「if(CLOSE<2.3,ROC(OPEN),HIGH)」のような式があり、ROC がカスタム関数である場合。条件「CLOSE<2.3」が評価されている場合、「ROC(OPEN)」の結果は得られますか?

2) "If" ステートメントをオーバーライドするにはどうすればよいですか? 以下の場合、「listOpen」の各要素に対して条件付きチェックを実行したいと思います。条件が TRUE と評価された場合、「listROC」から条件が真と評価されたインデックスの値を返す必要があります。それ以外の場合は、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 ステートメントを定義することもできます。


しかし、あなたの問題は、CLOSEandOPENが静的な値であると想定されているため、代わりに'CLOSE'andのような文字列としてエスケープする必要があることだと思います'OPEN'。または、パラメーターとして宣言され、それに応じて処理されます。https://ncalc.codeplex.com/wikipage?title=パラメータ

于 2015-01-28T15:09:43.537 に答える
0

あなたが達成しようとしていることを理解することはできません。if の動作を組み込みのようにしたくない場合は、「if」をオーバーライドすることはできません。式で IF() や Filter() などの他の単語を使用します。

于 2012-04-19T04:44:54.103 に答える