Free cookie consent management tool by TermsFeed Policy Generator

source: branches/sluengo/HeuristicLab.Problems.TradeRules/Interpreter.cs @ 9283

Last change on this file since 9283 was 9262, checked in by sluengo, 12 years ago
File size: 29.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
9using HeuristicLab.Parameters;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11using HeuristicLab.Problems.DataAnalysis.Symbolic;
12using HeuristicLab.Problems.DataAnalysis;
13using System.Threading;
14using HeuristicLab.Problems.TradeRules.Symbols;
15
16namespace HeuristicLab.Problems.TradeRules
17{
18    [StorableClass]
19    [Item("Interpreter", "Represents a grammar for Trading Problems")]
20    public sealed class Interpreter : ParameterizedNamedItem, ITradeRulesExpresionTree
21    {
22        private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
23        private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
24        private int initialTraining;
25        private int initialTest;
26        [ThreadStatic]
27        private static Dictionary<ISymbolicExpressionTreeNode, double> signalCache;
28        [ThreadStatic]
29        private static Dictionary<ISymbolicExpressionTreeNode, double> firstEMACache;
30        [ThreadStatic]
31        private static Dictionary<ISymbolicExpressionTreeNode, double> secondEMACache;
32        [ThreadStatic]
33        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIPositiveCache;
34        [ThreadStatic]
35        private static Dictionary<ISymbolicExpressionTreeNode, double> RSINegativeCache;
36        [ThreadStatic]
37        private static Dictionary<ISymbolicExpressionTreeNode, double> RSICache;
38        [ThreadStatic]
39        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIOutputCache;
40
41        #region private classes
42        //This class manipulate the instructions of the stack
43        private class InterpreterState
44        {
45            private double[] argumentStack;
46            private int argumentStackPointer;
47            private Instruction[] code;
48            private int pc;
49            public int ProgramCounter
50            {
51                get { return pc; }
52                set { pc = value; }
53            }
54            internal InterpreterState(Instruction[] code, int argumentStackSize)
55            {
56                this.code = code;
57                this.pc = 0;
58                if (argumentStackSize > 0)
59                {
60                    this.argumentStack = new double[argumentStackSize];
61                }
62                this.argumentStackPointer = 0;
63            }
64
65            internal void Reset()
66            {
67                this.pc = 0;
68                this.argumentStackPointer = 0;
69            }
70
71            internal Instruction NextInstruction()
72            {
73                return code[pc++];
74            }
75            private void Push(double val)
76            {
77                argumentStack[argumentStackPointer++] = val;
78            }
79            private double Pop()
80            {
81                return argumentStack[--argumentStackPointer];
82            }
83
84            internal void CreateStackFrame(double[] argValues)
85            {
86                // push in reverse order to make indexing easier
87                for (int i = argValues.Length - 1; i >= 0; i--)
88                {
89                    argumentStack[argumentStackPointer++] = argValues[i];
90                }
91                Push(argValues.Length);
92            }
93
94            internal void RemoveStackFrame()
95            {
96                int size = (int)Pop();
97                argumentStackPointer -= size;
98            }
99
100            internal double GetStackFrameValue(ushort index)
101            {
102                // layout of stack:
103                // [0]   <- argumentStackPointer
104                // [StackFrameSize = N + 1]
105                // [Arg0] <- argumentStackPointer - 2 - 0
106                // [Arg1] <- argumentStackPointer - 2 - 1
107                // [...]
108                // [ArgN] <- argumentStackPointer - 2 - N
109                // <Begin of stack frame>
110                return argumentStack[argumentStackPointer - index - 2];
111            }
112        }
113
114        //Operation codes
115        private class OpCodes
116        {
117            public const byte Add = 1;
118            public const byte Sub = 2;
119            public const byte Mul = 3;
120
121            public const byte GT = 5;
122            public const byte LT = 6;
123
124            public const byte AND = 7;
125            public const byte OR = 8;
126            public const byte NOT = 9;
127            public const byte BOOLEAN = 10;
128
129            public const byte Average = 11;
130            public const byte MACD = 12;
131
132            public const byte Variable = 13;
133            public const byte Constant = 14;
134            public const byte ConstantInt = 16;
135            public const byte BoolConstant = 15;
136            public const byte Max = 17;
137            public const byte Min = 18;
138            public const byte Lag = 19;
139            public const byte RSI = 20;
140        }
141        #endregion
142
143        #region IStatefulItem
144        public void InitializeState()
145        {
146            EvaluatedSolutions.Value = 0;
147        }
148
149        public void ClearState()
150        {
151        }
152        #endregion
153
154        private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
155      { typeof(Addition), OpCodes.Add },
156      { typeof(Subtraction), OpCodes.Sub },
157      { typeof(Multiplication), OpCodes.Mul },
158      { typeof(Constant), OpCodes.Constant },
159      { typeof(BoolConstant), OpCodes.BoolConstant },
160      { typeof(ConstantInt), OpCodes.ConstantInt },
161      { typeof(GreaterThan), OpCodes.GT },
162      { typeof(LessThan), OpCodes.LT },
163      { typeof(And), OpCodes.AND },
164      { typeof(Or), OpCodes.OR },
165      { typeof(Not), OpCodes.NOT},
166      { typeof(AverageTrade), OpCodes.Average},
167      { typeof(MACD), OpCodes.MACD},
168      { typeof(RSI), OpCodes.RSI},
169      { typeof(Max), OpCodes.Max},
170      { typeof(Min), OpCodes.Min},
171      { typeof(Lag), OpCodes.Lag},
172      { typeof(HeuristicLab.Problems.DataAnalysis.Symbolic.Variable), OpCodes.Variable },
173    };
174
175        public override bool CanChangeName
176        {
177            get { return false; }
178        }
179        public override bool CanChangeDescription
180        {
181            get { return false; }
182        }
183
184        #region parameter properties
185        public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter
186        {
187            get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
188        }
189
190        public IValueParameter<IntValue> EvaluatedSolutionsParameter
191        {
192            get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
193        }
194        #endregion
195
196        #region properties
197        public BoolValue CheckExpressionsWithIntervalArithmetic
198        {
199            get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
200            set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
201        }
202
203        public IntValue EvaluatedSolutions
204        {
205            get { return EvaluatedSolutionsParameter.Value; }
206            set { EvaluatedSolutionsParameter.Value = value; }
207        }
208        #endregion
209
210
211       
212
213        private double Evaluate(Dataset dataset, ref int row, InterpreterState state)
214        {
215            Instruction currentInstr = state.NextInstruction();
216
217            switch (currentInstr.opCode)
218            {
219                case OpCodes.Add:
220                    {
221                        double s = Evaluate(dataset, ref row, state);
222                        for (int i = 1; i < currentInstr.nArguments; i++)
223                        {
224                            s += Evaluate(dataset, ref row, state);
225                        }
226                        return s;
227                    }
228                case OpCodes.Sub:
229                    {
230                        double s = Evaluate(dataset, ref row, state);
231                        for (int i = 1; i < currentInstr.nArguments; i++)
232                        {
233                            s -= Evaluate(dataset, ref row, state);
234                        }
235                        if (currentInstr.nArguments == 1) s = -s;
236                        return s;
237                    }
238                case OpCodes.Mul:
239                    {
240                        double p = Evaluate(dataset, ref row, state);
241                        for (int i = 1; i < currentInstr.nArguments; i++)
242                        {
243                            p *= Evaluate(dataset, ref row, state);
244                        }
245                        return p;
246                    }
247                case OpCodes.Average:
248                    {
249                        double sum = Evaluate(dataset, ref row, state);
250                        int integerValue = (int) Math.Floor(sum);
251                        if (integerValue > 100) integerValue = 100;
252                        if (row < integerValue)
253                        {
254                            string variableName = dataset.GetValue(row, 3);
255                            double inferiorValue = Convert.ToDouble(variableName);
256                            return inferiorValue/(row+1);
257                        }
258                        else
259                        {
260                            string variableName = dataset.GetValue(row, 3);
261                            double meanValue1 = Convert.ToDouble(variableName);
262                            string variableName2 = dataset.GetValue((row - integerValue), 3);
263                            double meanValue2 = Convert.ToDouble(variableName2);
264                            return (meanValue1 - meanValue2) / integerValue;
265                        }
266                    }
267                case OpCodes.AND:
268                    {
269                        double result = Evaluate(dataset, ref row, state);
270                        for (int i = 1; i < currentInstr.nArguments; i++)
271                        {
272                            if (result > 0.0) result = Evaluate(dataset, ref row, state);
273                            else
274                            {
275                                SkipInstructions(state);
276                            }
277                        }
278                        return result > 0.0 ? 1.0 : -1.0;
279                    }
280                case OpCodes.OR:
281                    {
282                        double result = Evaluate(dataset, ref row, state);
283                        for (int i = 1; i < currentInstr.nArguments; i++)
284                        {
285                            if (result <= 0.0) result = Evaluate(dataset, ref row, state);
286                            else
287                            {
288                                SkipInstructions(state);
289                            }
290                        }
291                        return result > 0.0 ? 1.0 : -1.0;
292                    }
293                case OpCodes.NOT:
294                    {
295                        return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
296                    }
297
298                case OpCodes.BOOLEAN:
299                    {
300                        var booleanTreeNode = currentInstr.dynamicNode as BoolConstantTreeNode;
301                        return booleanTreeNode.Value;
302                    }
303                case OpCodes.GT:
304                    {
305                        double x = Evaluate(dataset, ref row, state);
306                        double y = Evaluate(dataset, ref row, state);
307                        if (x > y) return 1.0;
308                        else return -1.0;
309                    }
310                case OpCodes.LT:
311                    {
312                        double x = Evaluate(dataset, ref row, state);
313                        double y = Evaluate(dataset, ref row, state);
314                        if (x < y) return 1.0;
315                        else return -1.0;
316                    }
317                case OpCodes.Variable:
318                    {
319                        if (row < 0 || row >= dataset.Rows)
320                            return double.NaN;
321                        var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
322                        return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
323                    }
324                case OpCodes.Constant:
325                    {
326                        var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
327                        return constTreeNode.Value;
328                    }
329                case OpCodes.BoolConstant:
330                    {
331                        var boolConstTreeNode = currentInstr.dynamicNode as BoolConstantTreeNode;
332                        return boolConstTreeNode.Value;
333                    }
334                case OpCodes.ConstantInt:
335                    {
336                        var constIntTreeNode = currentInstr.dynamicNode as ConstantIntTreeNode;
337                        return constIntTreeNode.Value;
338                    }
339                case OpCodes.Max:
340                    {
341                        int n = (int) Evaluate(dataset, ref row, state);
342                        double max = Double.NegativeInfinity;
343                        int i = Math.Min(n,row);
344                        while(i>=0)
345                        {
346                            int position = row - i;
347                            string variableName = dataset.GetValue(position, 2);
348                            double intValue = Convert.ToDouble(variableName);
349                            if (intValue>max) max = intValue;
350                        i--;
351                        }
352                        return max;
353                    }
354                case OpCodes.Min:
355                    {
356                        int n = (int)Evaluate(dataset, ref row, state);
357                        double min = Double.NegativeInfinity;
358                        int i = Math.Min(n, row);
359                        while (i >= 0)
360                        {
361                            int position = row - i;
362                            string variableName = dataset.GetValue(position, 2);
363                            double intValue = Convert.ToDouble(variableName);
364                            if (intValue < min) min = intValue;
365                            i--;
366                        }
367                          return min;
368                    }
369                case OpCodes.Lag:
370                    {
371                        int n = (int) Evaluate(dataset, ref row, state);
372                        if (n>row) return 0;
373                        int position = row - n;
374                        string variableName = dataset.GetValue(position, 2);
375                        double intValue = Convert.ToDouble(variableName);
376                        return intValue;
377                    }
378                case OpCodes.MACD:
379                    {
380                        var MACDNode = currentInstr.dynamicNode;
381                        //Taking the number of the days for each EMA
382                        double firstEMA = Evaluate(dataset, ref row, state);
383                        double secondEMA = Evaluate(dataset, ref row, state);
384                        double signal = Evaluate(dataset, ref row, state);
385
386                        //Calculating the factor for each EMA
387                        double factor = 2.0 / (firstEMA + 1.0);
388                        double factor2 = 2.0 / (secondEMA + 1.0);
389                        double factor3 = 2.0 / (signal + 1.0);
390
391                        //Initiation of the variables
392                        double firstElementEMA = -1000000;
393                        double secondElementEMA = -100000;
394                        double signalValue = -100000;
395                        double macd = 0;
396
397                        //Check if this MACD has previous values and retrieve them
398                        if (firstEMACache.ContainsKey(MACDNode)) firstElementEMA = firstEMACache[MACDNode];
399                        if (secondEMACache.ContainsKey(MACDNode)) secondElementEMA = secondEMACache[MACDNode];
400                        if (signalCache.ContainsKey(MACDNode)) signalValue = signalCache[MACDNode];
401
402                        //Calculate the first value in the training for the two EMAs and the signal.
403                        if (row <= initialTraining || row == initialTest)
404                        {
405                            double[] meanValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, (row + 1))).ToArray();
406                            firstElementEMA = meanValues[0];
407                            secondElementEMA = meanValues[0];
408                            double max = (Math.Max(firstEMA, secondEMA) - 1);//The first macd happens when the longest EMA has its first value. We need -1 because row begin in 0.
409                            for (int i = 1; i <= row; i++)
410                            {
411                                firstElementEMA = meanValues[i] * factor + (1 - factor) * firstElementEMA;
412                                secondElementEMA = meanValues[i] * factor2 + (1 - factor2) * secondElementEMA;
413                                if (i == max) signalValue = firstElementEMA - secondElementEMA;//First signal equals to macd.
414                                else if (i > max)//Calculation for the next signals
415                                {
416                                    macd = firstElementEMA - secondElementEMA;
417                                    signalValue = macd * factor3 + (1 - factor3) * signalValue;
418                                }
419                            }
420                        }
421                        else  //The rest of the rows are calculating with the standard EMA formula
422                        {
423                            //Retrieve the dataset values
424                            string variableName = dataset.GetValue(row, 2);
425                            double meanValue1 = Convert.ToDouble(variableName);
426
427                            //Calculating EMA
428                            firstElementEMA = meanValue1 * factor + (1 - factor) * firstElementEMA;
429                            secondElementEMA = meanValue1 * factor2 + (1 - factor2) * secondElementEMA;
430
431                            //Calculating signal
432                            macd = firstElementEMA - secondElementEMA;
433                            signalValue = macd * factor3 + (1 - factor3) * signalValue;
434                        }
435
436                        //Save the values for the next iteration
437                        firstEMACache[MACDNode] = firstElementEMA;
438                        secondEMACache[MACDNode] = secondElementEMA;
439                        signalCache[MACDNode] = signalValue;
440
441                        macd = firstElementEMA - secondElementEMA;
442                        return macd > signalValue ? 1.0 : -1.0;
443                    }
444                case OpCodes.RSI:
445                   {
446                       
447                       //Taking the number of the days for EMA
448                       double numberOfDays = Evaluate(dataset, ref row, state);
449
450                       //Calculate the factor for the EMA
451                       double factor = 1.0 / numberOfDays;
452
453                       double positiveEMA = 0;
454                       double negativeEMA = 0;
455                       double yesterdayRSI = double.NegativeInfinity;
456                       double todayRSI = double.NegativeInfinity;
457                       double outputRSI = double.NegativeInfinity;
458                       //Retrieve EMA values
459                       if (RSIPositiveCache.ContainsKey(currentInstr.dynamicNode)) positiveEMA = RSIPositiveCache[currentInstr.dynamicNode];
460                       if (RSINegativeCache.ContainsKey(currentInstr.dynamicNode)) negativeEMA = RSINegativeCache[currentInstr.dynamicNode];
461                       if (RSICache.ContainsKey(currentInstr.dynamicNode)) yesterdayRSI = RSICache[currentInstr.dynamicNode];
462                       if (RSIOutputCache.ContainsKey(currentInstr.dynamicNode)) outputRSI = RSIOutputCache[currentInstr.dynamicNode];
463
464                       if (row == initialTraining || row == initialTest)
465                       {
466                           double[] closeValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, (row + 1))).ToArray();
467                           outputRSI = -1.0;
468                           for (int i = 1; i <= row; i++)
469                           {
470                               if (numberOfDays>=i)
471                               {
472                                   if ((closeValues[i] - closeValues[i - 1]) > 0) positiveEMA = ((closeValues[i] - closeValues[i - 1])+positiveEMA);
473                                   else negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) + negativeEMA;
474                                   if (numberOfDays == i)
475                                   {
476                                       positiveEMA = positiveEMA/numberOfDays;
477                                       negativeEMA = negativeEMA / numberOfDays;
478                                       yesterdayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
479                                   }
480                               }else{
481                                    if ((closeValues[i] - closeValues[i - 1]) > 0)
482                                    {
483                                        positiveEMA = (closeValues[i]-closeValues[i-1]) * factor + (1 - factor) * positiveEMA;
484                                        negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
485                                    }
486                                    else
487                                    {
488                                        positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
489                                        negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) * factor + (1 - factor) * negativeEMA;
490                                    }
491                                   
492                                    todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
493
494                                    if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
495                                   else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
496                                   yesterdayRSI = todayRSI;
497                               }
498                           }
499                       }
500                       else
501                       {
502                           string todayCloseString = dataset.GetValue(row, 2);
503                           string yesterdayCloseString = dataset.GetValue((row - 1), 2);
504                           double todayClose = Convert.ToDouble(todayCloseString);
505                           double yesterdayClose = Convert.ToDouble(yesterdayCloseString);
506
507                           //Calculating EMA
508                           if ((todayClose - yesterdayClose) > 0)
509                           {
510                               positiveEMA = (todayClose-yesterdayClose) * factor + (1 - factor) * positiveEMA;
511                               negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
512                           }
513                           else
514                           {
515                               positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
516                               negativeEMA = Math.Abs(todayClose - yesterdayClose) * factor + (1 - factor) * negativeEMA;
517                           }
518                           todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
519                           if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
520                           else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
521                       }
522                       
523                       //Save positive and negative EMA for the next iteration
524                       RSIPositiveCache[currentInstr.dynamicNode] = positiveEMA;
525                       RSINegativeCache[currentInstr.dynamicNode] = negativeEMA;
526                       RSICache[currentInstr.dynamicNode] = todayRSI;
527                       RSIOutputCache[currentInstr.dynamicNode] = outputRSI;   
528                       
529                       return outputRSI;
530                    }
531               
532                default: throw new NotSupportedException();
533            }
534        }
535
536        private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode)
537        {
538            if (symbolToOpcode.ContainsKey(treeNode.Symbol.GetType()))
539                return symbolToOpcode[treeNode.Symbol.GetType()];
540            else
541                throw new NotSupportedException("Symbol: " + treeNode.Symbol);
542        }
543
544        // skips a whole branch
545        private void SkipInstructions(InterpreterState state)
546        {
547            int i = 1;
548            while (i > 0)
549            {
550                i += state.NextInstruction().nArguments;
551                i--;
552            }
553        }
554        [StorableConstructor]
555        private Interpreter(bool deserializing) : base(deserializing) { }
556        private Interpreter(Interpreter original, Cloner cloner) : base(original, cloner) { }
557        public override IDeepCloneable Clone(Cloner cloner)
558        {
559            return new Interpreter(this, cloner);
560        }
561
562        public Interpreter()
563            : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")
564        {
565            Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
566            Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
567        }
568
569        [StorableHook(HookType.AfterDeserialization)]
570        private void AfterDeserialization()
571        {
572            if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
573                Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
574        }
575        public void setInitialTraining(int initialTraining)
576        {
577            this.initialTraining = initialTraining;
578        }
579
580        public void setInitialTest(int initialTest)
581        {
582            this.initialTest = initialTest;
583        }
584
585        public void clearVariables()
586        {
587            signalCache.Clear();
588            firstEMACache.Clear();
589            secondEMACache.Clear();
590            RSIPositiveCache.Clear();
591            RSINegativeCache.Clear();
592            RSICache.Clear();
593            RSIOutputCache.Clear();
594        }
595
596        //Take the symbolic expression values of the tree
597        public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows)
598        {
599            if (CheckExpressionsWithIntervalArithmetic.Value)
600            throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
601            EvaluatedSolutions.Value++; // increment the evaluated solutions counter
602            var compiler = new SymbolicExpressionTreeCompiler();
603            Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);//Take the type of symbol
604            int necessaryArgStackSize = 0;
605            for (int i = 0; i < code.Length; i++)
606            {
607                Instruction instr = code[i];
608                if (instr.opCode == OpCodes.Variable)
609                {
610                    var variableTreeNode = instr.dynamicNode as VariableTreeNode;
611                    instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
612                    code[i] = instr;
613                }
614            }
615
616
617            if (signalCache == null) signalCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
618            if (firstEMACache == null) firstEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
619            if (secondEMACache == null) secondEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
620            if (RSIPositiveCache == null) RSIPositiveCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
621            if (RSINegativeCache == null) RSINegativeCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
622            if (RSICache == null) RSICache = new Dictionary<ISymbolicExpressionTreeNode, double>();
623            if (RSIOutputCache == null) RSIOutputCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
624                                 
625                                       
626                                        var state = new InterpreterState(code, necessaryArgStackSize);
627                                        //Evaluate each row of the datase
628                                        foreach (var rowEnum in rows)
629                                        {
630                                            int row = rowEnum;
631                                            state.Reset();
632                                            if (row < initialTraining) yield return -1;
633                                            else yield return Evaluate(dataset, ref row, state);
634                                        }
635                }
636        }
637
638    }
639
Note: See TracBrowser for help on using the repository browser.