Index: branches/sluengo/HeuristicLab.Problems.TradeRules/DataAnalysisSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/DataAnalysisSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/DataAnalysisSolution.cs	(revision 9262)
@@ -0,0 +1,168 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class DataAnalysisSolution : ResultCollection, IDataAnalysisSolution {
+    private const string ModelResultName = "Model";
+    private const string ProblemDataResultName = "ProblemData";
+
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
+    }
+
+    #region properties
+    public IDataAnalysisModel Model {
+      get { return (IDataAnalysisModel)this[ModelResultName].Value; }
+      protected set {
+        if (this[ModelResultName].Value != value) {
+          if (value != null) {
+            this[ModelResultName].Value = value;
+            OnModelChanged();
+          }
+        }
+      }
+    }
+
+    public IDataAnalysisProblemData ProblemData {
+      get { return (IDataAnalysisProblemData)this[ProblemDataResultName].Value; }
+      set {
+        if (this[ProblemDataResultName].Value != value) {
+          if (value != null) {
+            ProblemData.Changed -= new EventHandler(ProblemData_Changed);
+            this[ProblemDataResultName].Value = value;
+            ProblemData.Changed += new EventHandler(ProblemData_Changed);
+            OnProblemDataChanged();
+          }
+        }
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
+      : base(original, cloner) {
+      name = original.Name;
+      description = original.Description;
+    }
+    public DataAnalysisSolution(IDataAnalysisModel model, IDataAnalysisProblemData problemData)
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      Add(new Result(ModelResultName, "The data analysis model.", model));
+      Add(new Result(ProblemDataResultName, "The data analysis problem data.", problemData));
+
+      problemData.Changed += new EventHandler(ProblemData_Changed);
+    }
+
+    protected abstract void RecalculateResults();
+
+    private void ProblemData_Changed(object sender, EventArgs e) {
+      OnProblemDataChanged();
+    }
+
+    public event EventHandler ModelChanged;
+    protected virtual void OnModelChanged() {
+      RecalculateResults();
+      var listeners = ModelChanged;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ProblemDataChanged;
+    protected virtual void OnProblemDataChanged() {
+      RecalculateResults();
+      var listeners = ProblemDataChanged;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+
+    #region INamedItem Members
+    [Storable]
+    protected string name;
+    public string Name {
+      get { return name; }
+      set {
+        if (!CanChangeName) throw new NotSupportedException("Name cannot be changed.");
+        if (!(name.Equals(value) || (value == null) && (name == string.Empty))) {
+          CancelEventArgs<string> e = value == null ? new CancelEventArgs<string>(string.Empty) : new CancelEventArgs<string>(value);
+          OnNameChanging(e);
+          if (!e.Cancel) {
+            name = value == null ? string.Empty : value;
+            OnNameChanged();
+          }
+        }
+      }
+    }
+    public virtual bool CanChangeName {
+      get { return true; }
+    }
+    [Storable]
+    protected string description;
+    public string Description {
+      get { return description; }
+      set {
+        if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed.");
+        if (!(description.Equals(value) || (value == null) && (description == string.Empty))) {
+          description = value == null ? string.Empty : value;
+          OnDescriptionChanged();
+        }
+      }
+    }
+    public virtual bool CanChangeDescription {
+      get { return true; }
+    }
+
+    public override string ToString() {
+      return Name;
+    }
+
+    public event EventHandler<CancelEventArgs<string>> NameChanging;
+    protected virtual void OnNameChanging(CancelEventArgs<string> e) {
+      var handler = NameChanging;
+      if (handler != null) handler(this, e);
+    }
+
+    public event EventHandler NameChanged;
+    protected virtual void OnNameChanged() {
+      var handler = NameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    public event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged() {
+      var handler = DescriptionChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/EvaluatorTradeRules.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/EvaluatorTradeRules.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/EvaluatorTradeRules.cs	(revision 9262)
@@ -0,0 +1,75 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [Item("Trade Rules Evaluator", "Calculates the profit")]
+    [StorableClass]
+    public class EvaluatorTradeRules : TradeRulesSingleObjectiveEvaluator
+    {
+        private static int initialTraining;
+        private static int initialTest;
+        public override bool Maximization { get { return true; } }
+
+        [StorableConstructor]
+        protected EvaluatorTradeRules(bool deserializing) : base(deserializing) { }
+        protected EvaluatorTradeRules(EvaluatorTradeRules original, Cloner cloner)
+            : base(original, cloner)
+        {
+        }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new EvaluatorTradeRules(this, cloner);
+        }
+
+        public EvaluatorTradeRules() : base() { }
+
+        public override IOperation Apply()
+        {
+            var solution = SymbolicExpressionTreeParameter.ActualValue;
+            IEnumerable<int> rows = GenerateRowsToEvaluate();
+            initialTraining = initialTrainingValue();
+            initialTest = initialTestValue();
+            double quality = Calculate((ITradeRulesExpresionTree) SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+            QualityParameter.ActualValue = new DoubleValue(quality);
+            ITradeRulesExpresionTree interpreter = (ITradeRulesExpresionTree)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+            interpreter.clearVariables();
+            return base.Apply();
+        }
+
+        public static double Calculate(ITradeRulesExpresionTree interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows)
+        {
+            interpreter.setInitialTraining(initialTraining);
+            interpreter.setInitialTest(initialTest);
+            IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+            
+            double tradingCash = OnlineTradeRulesCalculator.Calculate(estimatedValues, problemData, problemData.TrainingIndices);
+            
+            return tradingCash;
+        }
+
+        public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows)
+        {
+            SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+            EstimationLimitsParameter.ExecutionContext = context;
+
+            double r2 = Calculate((ITradeRulesExpresionTree) SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+            SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+            EstimationLimitsParameter.ExecutionContext = null;
+         
+
+            return r2;
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/OnlineTradeRulesCalculator.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/OnlineTradeRulesCalculator.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/OnlineTradeRulesCalculator.cs	(revision 9262)
@@ -0,0 +1,228 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class OnlineTradeRulesCalculator
+    {
+        public static double Calculate(IEnumerable<double> estimatedValues, IRegressionProblemData problemData, IEnumerable<int> rows)
+        {/*
+            const double commission = 0.25;
+            const double EAR = 4.00;  //Effective Anual Rate 
+
+            double DayRat = 0; //One day interest
+            double interest = 0.0; // Interest for one day
+            double[] arrayDate = problemData.Dataset.GetDoubleValues("\"Date\"").ToArray(); //Array with all dates in UNIX format
+
+            //int count = rows.ToList()[0];
+ 
+            bool intoMarket = false;//Equivalent to be into the market
+            int totalTradeDays = 0;
+            int numberTrades = 0;
+            int tradeDays = 0;
+            double dayBefore = 0.0;
+            double yesterday = 0.0;
+            double buyPrice = 0.0;
+            double sellPrice = 0.0;
+            string stringPrice = "";
+            int nShares = 0;
+            double cash = 10000.00;
+            double expend = 0.0;
+            double equity = 0.0;
+            double profit1 = 0.0;
+            double charged = 0.0;
+
+            IEnumerator<int> initialRow = rows.GetEnumerator();
+            initialRow.MoveNext();
+            int numDays1 = (int)arrayDate[initialRow.Current-1];
+            int numDays2 = (int) arrayDate[(initialRow.Current)];
+            int count = initialRow.Current + 1;
+            
+            IEnumerator<double> enumerator = estimatedValues.GetEnumerator();
+            enumerator.MoveNext();
+            dayBefore = enumerator.Current;
+            enumerator.MoveNext();
+            yesterday = enumerator.Current;
+
+            DayRat = 360 * (Math.Pow((1 + (EAR / 100)), (1 / 360)) - 1);
+
+            while (enumerator.MoveNext())
+            {
+                if (!intoMarket)
+                {
+                    if (dayBefore == -1 && yesterday == 1)
+                    {
+                        intoMarket = true;
+                        stringPrice = problemData.Dataset.GetValue(count, 0); //Extracting Open values
+                        buyPrice = Convert.ToDouble(stringPrice);
+                        totalTradeDays++; numberTrades++; tradeDays++; //Increasing trading variables
+                        nShares = (int)Math.Floor(cash / (buyPrice * (1.0 + commission / 100)));
+                        expend = buyPrice * nShares * (1 + commission / 100);
+                        cash = cash - expend + interest;
+                        equity = cash + nShares * buyPrice * (1 - commission / 100);
+                        interest = cash * Math.Pow((1 + DayRat / 360), numDays2) - cash;
+                    }
+                    else  //Dia normal fuera del mercado
+                    {
+                        cash = cash + interest;
+                        equity = equity + cash;
+                        interest = cash * Math.Pow((1 + DayRat / 360), numDays2) - cash;
+                    }
+
+                }
+                else if (dayBefore == 1 && yesterday == -1)
+                {
+                    intoMarket = false;
+                    stringPrice = problemData.Dataset.GetValue(count, 0); //Extracting Open values
+                    sellPrice = Convert.ToDouble(stringPrice);
+                    profit1 += sellPrice - buyPrice;
+                    charged = sellPrice * nShares * (1 - commission / 100);
+                    cash = cash + charged + interest;
+                    equity = cash;
+                    interest = cash * Math.Pow((1 + DayRat / 360), numDays2) - cash;
+                    nShares = 0;
+                }
+                else
+                {
+                    cash = cash + interest;
+                    tradeDays += numDays1;
+                    totalTradeDays += numDays1;
+                    equity = cash + nShares * Convert.ToDouble(problemData.Dataset.GetValue(count, 0)) * (1 - commission / 100);
+                    interest = cash * Math.Pow((1 + DayRat / 360), numDays2) - cash;
+                }
+
+                dayBefore = yesterday;
+                yesterday = enumerator.Current;
+                numDays1 = numDays2;
+                numDays2 = (int) arrayDate[count];
+                count++;
+            }
+            if (intoMarket)
+            {
+                intoMarket = false;
+                stringPrice = problemData.Dataset.GetValue(count, 0); //Extracting Open values
+                sellPrice = Convert.ToDouble(stringPrice);
+                profit1 += sellPrice - buyPrice;
+                charged = sellPrice * nShares * (1 - commission / 100);
+                cash = cash + charged + interest;
+                equity = cash;
+                nShares = 0;
+            }
+            return numDays1;*/
+
+            const double commission = 0.25;
+            const double EAR = 4.00;  //Effective Anual Rate 
+
+            double DayRat = 0; //One day interest
+            double interest = 0.0; // Interest for one day
+            double[] arrayDate = problemData.Dataset.GetDoubleValues("\"Date\"").ToArray(); //Array with all dates in UNIX format
+            int nDias1 = 0;
+            int nDias2 = 0;
+
+
+            bool intoMarket = false;//Equivalent to be into the market
+            int totalTradeDays = 0;
+            int numberTrades = 0;
+            int tradeDays = 0;
+            double buyPrice = 0.0;
+            double sellPrice = 0.0;
+            string stringPrice = "";
+            int nShares = 0;
+            double cash = 10000.00;
+            double expend = 0.0;
+            double equity = 0.0;
+            double profit1 = 0.0;
+            double charged = 0.0;
+
+            //SECOND EVALUATOR
+            var enumerator = estimatedValues.GetEnumerator();
+            int count = rows.ToList()[2];
+            int count2 = 2;
+            int date1 = (int)arrayDate[rows.ToList()[0]];
+            int date2 = (int)arrayDate[rows.ToList()[1]];
+
+            enumerator.MoveNext();
+            double dayBefore = enumerator.Current;
+            enumerator.MoveNext();
+            double yesterday = enumerator.Current;
+            
+            DayRat = 268 * (Math.Pow((1 + (EAR / 100)),(1 / 268)) - 1);
+            nDias2 = date2 - date1;
+            
+            while (enumerator.MoveNext())
+            {
+                if (!intoMarket)
+                {
+                    if (dayBefore == -1 && yesterday == 1)
+                    {
+                        intoMarket = true;
+                        stringPrice = problemData.Dataset.GetValue(count, 1); //Extracting Open values
+                        buyPrice = Convert.ToDouble(stringPrice);
+                        totalTradeDays++; numberTrades++; tradeDays++; //Increasing trading variables
+                        nShares = (int)Math.Floor(cash / (buyPrice * (1.0 + commission / 100)));
+                        expend = buyPrice * nShares * (1 + commission / 100);
+                        cash = cash - expend + interest;
+                        equity = cash + nShares * buyPrice * (1 - commission / 100);
+                        interest = cash * Math.Pow((1 + DayRat / 268), nDias2) - cash;
+                    }
+                    else  //Dia normal fuera del mercado
+                    {
+                        tradeDays++;
+                        totalTradeDays++;
+                        cash = cash + interest;
+                        equity = equity+cash;
+                        interest = cash * Math.Pow((1 + DayRat / 268), nDias2) - cash;
+                    }
+                }
+                else if (dayBefore == 1 && yesterday == -1)
+                {
+                    intoMarket = false;
+                    stringPrice = problemData.Dataset.GetValue(count, 1); //Extracting Open values
+                    sellPrice = Convert.ToDouble(stringPrice);
+                    profit1 += sellPrice - buyPrice;
+                    charged = sellPrice * nShares * (1 - commission / 100);
+                    cash = cash + charged+interest;
+                    equity = cash;
+                    interest = cash + Math.Pow((1 + DayRat / 268), nDias2) - cash;
+                    nShares = 0;
+                }
+                else
+                {
+                    cash = cash + interest;
+                    tradeDays++;
+                    totalTradeDays++;
+                    equity = cash + nShares * Convert.ToDouble(problemData.Dataset.GetValue(count,1)) * (1 - commission / 100);
+                    interest = cash * Math.Pow((1 + DayRat / 268), nDias2) - cash;
+                }
+
+                dayBefore = yesterday;
+                yesterday = enumerator.Current;
+                date1 = date2;
+                date2 = (int)arrayDate[rows.ToList()[count2]];
+                
+                int nDiasAux = nDias1;
+                nDias1 = nDias2;
+                nDias2 = date2-date1;
+
+                count++;
+                count2++;
+            }
+
+            if (intoMarket)
+            {
+                intoMarket = false;
+                stringPrice = problemData.Dataset.GetValue((count-1), 1); //Extracting Open values
+                sellPrice = Convert.ToDouble(stringPrice);
+                profit1 += sellPrice - buyPrice;
+                charged = sellPrice * nShares * (1 - commission / 100);
+                cash = cash + charged + interest;
+                equity = cash;
+                nShares = 0;
+            }
+            return cash;
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisEvaluator.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisEvaluator.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisEvaluator.cs	(revision 9262)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  public abstract class TradeRulesAnalysisEvaluator<T> : SingleSuccessorOperator,
+    ISymbolicDataAnalysisEvaluator<T>, ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator
+  where T : class, IDataAnalysisProblemData {
+    private const string RandomParameterName = "Random";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string EvaluationPartitionParameterName = "EvaluationPartition";
+    private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+
+    public override bool CanChangeName { get { return false; } }
+
+    #region parameter properties
+    public IValueLookupParameter<IRandom> RandomParameter {
+      get { return (IValueLookupParameter<IRandom>)Parameters[RandomParameterName]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+    }
+    public IValueLookupParameter<T> ProblemDataParameter {
+      get { return (IValueLookupParameter<T>)Parameters[ProblemDataParameterName]; }
+    }
+
+    public IValueLookupParameter<IntRange> EvaluationPartitionParameter {
+      get { return (IValueLookupParameter<IntRange>)Parameters[EvaluationPartitionParameterName]; }
+    }
+    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    public IValueLookupParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+    }
+    #endregion
+
+
+    [StorableConstructor]
+    protected TradeRulesAnalysisEvaluator(bool deserializing) : base(deserializing) { }
+    protected TradeRulesAnalysisEvaluator(TradeRulesAnalysisEvaluator<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public TradeRulesAnalysisEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IRandom>(RandomParameterName, "The random generator to use."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of the symbolic data analysis tree."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic data analysis solution encoded as a symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<T>(ProblemDataParameterName, "The problem data on which the symbolic data analysis solution should be evaluated."));
+      Parameters.Add(new ValueLookupParameter<IntRange>(EvaluationPartitionParameterName, "The start index of the dataset partition on which the symbolic data analysis solution should be evaluated."));
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The upper and lower limit that should be used as cut off value for the output values of symbolic data analysis trees."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
+    }
+
+    protected IEnumerable<int> GenerateRowsToEvaluate() {
+      return GenerateRowsToEvaluate(RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value);
+    }
+
+    protected int initialTrainingValue()
+    {
+        return EvaluationPartitionParameter.ActualValue.Start;
+    }
+    protected int initialTestValue()
+    {
+        return ProblemDataParameter.ActualValue.TestPartition.Start;
+    }
+
+    protected IEnumerable<int> GenerateRowsToEvaluate(double percentageOfRows) {
+
+
+      IEnumerable<int> rows;
+      int samplesStart = EvaluationPartitionParameter.ActualValue.Start;
+      int samplesEnd = EvaluationPartitionParameter.ActualValue.End;
+      int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
+      int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
+
+      if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
+
+      if (percentageOfRows.IsAlmost(1.0))
+        rows = Enumerable.Range(samplesStart, samplesEnd - samplesStart);
+      else {
+        int seed = RandomParameter.ActualValue.Next();
+        int count = (int)((samplesEnd - samplesStart) * percentageOfRows);
+        if (count == 0) count = 1;
+        rows = RandomEnumerable.SampleRandomNumbers(seed, samplesStart, samplesEnd, count);
+      }
+
+      return rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
+    }
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisSingleObjectiveEvaluator.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisSingleObjectiveEvaluator.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesAnalysisSingleObjectiveEvaluator.cs	(revision 9262)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.Collections.Generic;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.TradeRules {
+  [StorableClass]
+  public abstract class TradeRulesAnalysisSingleObjectiveEvaluator<T> : TradeRulesAnalysisEvaluator<T>, ISymbolicDataAnalysisSingleObjectiveEvaluator<T>
+   where T : class, IDataAnalysisProblemData {
+    private const string QualityParameterName = "Quality";
+    #region parameter properties
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
+    }
+    #endregion
+    #region properties
+    public abstract bool Maximization { get; }
+    #endregion
+    [StorableConstructor]
+    protected TradeRulesAnalysisSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    protected TradeRulesAnalysisSingleObjectiveEvaluator(TradeRulesAnalysisSingleObjectiveEvaluator<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected TradeRulesAnalysisSingleObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName, "The quality of the evaluated symbolic data analysis solution."));
+    }
+
+    public abstract double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, T problemData, IEnumerable<int> rows);
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesSingleObjectiveEvaluator.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesSingleObjectiveEvaluator.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Evaluator/TradeRulesSingleObjectiveEvaluator.cs	(revision 9262)
@@ -0,0 +1,100 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+namespace HeuristicLab.Problems.TradeRules {
+  [StorableClass]
+    public abstract class TradeRulesSingleObjectiveEvaluator : TradeRulesAnalysisSingleObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionSingleObjectiveEvaluator
+    {
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+    public bool ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value.Value; }
+      set { ApplyLinearScalingParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected TradeRulesSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    protected TradeRulesSingleObjectiveEvaluator(TradeRulesSingleObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    protected TradeRulesSingleObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(false)));
+      ApplyLinearScalingParameter.Hidden = true;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(false)));
+        ApplyLinearScalingParameter.Hidden = true;
+      }
+    }
+
+    [ThreadStatic]
+    private static double[] cache;
+
+    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues,
+      double lowerEstimationLimit, double upperEstimationLimit,
+      IOnlineCalculator calculator, int maxRows) {
+      if (cache == null || cache.GetLength(0) < maxRows) {
+        cache = new double[maxRows];
+      }
+
+      //calculate linear scaling
+      //the static methods of the calculator could not be used as it performs a check if the enumerators have an equal amount of elements
+      //this is not true if the cache is used
+      int i = 0;
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() && estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        cache[i] = estimated;
+        linearScalingCalculator.Add(estimated, target);
+        i++;
+      }
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+
+      //calculate the quality by using the passed online calculator
+      targetValuesEnumerator = targetValues.GetEnumerator();
+      var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha)
+        .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator();
+
+      while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) {
+        calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current);
+      }
+    }
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Grammar.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Grammar.cs	(revision 9260)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Grammar.cs	(revision 9262)
@@ -41,5 +41,5 @@
     private const string BooleanConstant = "Boolean Constant";
     private const string TradeMean = "Average Trade";
-    private const string MACDIndicator = "MACD Indicator";
+    private const string Indicators = "Indicators";
     private const string SerialTime = "Serial Operators";
       
@@ -64,7 +64,6 @@
 
         var mean = new AverageTrade();
-        var expMovAverage = new EMA();
         var macd = new MACD();
-        var RSI = new RSI();
+        var rsi = new RSI();
 
         var gt = new GreaterThan();
@@ -91,5 +90,5 @@
         var booleanConstantsSymbols = new GroupSymbol(BooleanConstant, new List<ISymbol> { boolean });
         var meanTradeSymbols = new GroupSymbol(TradeMean, new List<ISymbol> { mean});
-        var indicatorTradeSymbols = new GroupSymbol(MACDIndicator, new List<ISymbol> { macd,RSI, expMovAverage });
+        var indicatorTradeSymbols = new GroupSymbol(Indicators, new List<ISymbol> { macd,rsi});
         
         var serialTime = new GroupSymbol(SerialTime, new List<ISymbol> {max,min, lag });
@@ -110,10 +109,8 @@
         SetSubtreeCount(arithmeticSymbols, 2, 2);
         SetSubtreeCount(terminalSymbols, 0, 0);
-
         SetSubtreeCount(booleanConstantsSymbols, 0, 0);
         SetSubtreeCount(meanTradeSymbols, 1, 1);
         SetSubtreeCount(macd, 3, 3);
-        SetSubtreeCount(RSI, 1, 1);
-        SetSubtreeCount(expMovAverage, 1, 1);
+        SetSubtreeCount(rsi, 1, 1);
         SetSubtreeCount(comparisonSymbols, 2, 2);
         SetSubtreeCount(and, 2, 2);
@@ -124,11 +121,11 @@
 
       #region allowed child symbols configuration
-        //AddAllowedChildSymbol(StartSymbol, booleanOperationSymbols);
-        //AddAllowedChildSymbol(StartSymbol, comparisonSymbols);
-        AddAllowedChildSymbol(StartSymbol, expMovAverage);
+        AddAllowedChildSymbol(StartSymbol, booleanOperationSymbols);
+        AddAllowedChildSymbol(StartSymbol, comparisonSymbols);
 
         AddAllowedChildSymbol(booleanOperationSymbols, comparisonSymbols);
         AddAllowedChildSymbol(booleanOperationSymbols, booleanConstantsSymbols);
-        //AddAllowedChildSymbol(booleanOperationSymbols, indicatorTradeSymbols);
+        AddAllowedChildSymbol(booleanOperationSymbols, indicatorTradeSymbols);
+        AddAllowedChildSymbol(booleanOperationSymbols, booleanOperationSymbols);
 
         AddAllowedChildSymbol(comparisonSymbols, meanTradeSymbols);
@@ -142,8 +139,7 @@
         AddAllowedChildSymbol(arithmeticSymbols, serialTime);
 
+        AddAllowedChildSymbol(indicatorTradeSymbols, constantint);
         AddAllowedChildSymbol(serialTime, constantint);
-
-        AddAllowedChildSymbol(meanTradeSymbols, constantint);
-        AddAllowedChildSymbol(indicatorTradeSymbols, constantint);
+        AddAllowedChildSymbol(meanTradeSymbols, constantint);   
       #endregion
     }
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/HeuristicLab.Problems.TradeRules-1.0.csproj
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/HeuristicLab.Problems.TradeRules-1.0.csproj	(revision 9260)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/HeuristicLab.Problems.TradeRules-1.0.csproj	(revision 9262)
@@ -96,23 +96,36 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="AverageTrade.cs" />
-    <Compile Include="BoolConstant.cs" />
-    <Compile Include="BoolConstantTreeNode.cs" />
-    <Compile Include="ConstantInt.cs" />
-    <Compile Include="ConstantIntTreeNode.cs" />
-    <Compile Include="EMA.cs" />
-    <Compile Include="EvaluatorTradeRules.cs" />
+    <Compile Include="Symbols\AverageTrade.cs" />
+    <Compile Include="Symbols\BoolConstant.cs" />
+    <Compile Include="Symbols\BoolConstantTreeNode.cs" />
+    <Compile Include="Symbols\ConstantInt.cs" />
+    <Compile Include="Symbols\ConstantIntTreeNode.cs" />
+    <Compile Include="Evaluator\EvaluatorTradeRules.cs" />
     <Compile Include="Grammar.cs" />
     <Compile Include="Interpreter.cs" />
-    <Compile Include="Lag.cs" />
-    <Compile Include="MACD.cs" />
-    <Compile Include="Max.cs" />
-    <Compile Include="Min.cs" />
+    <Compile Include="Symbols\ITradeRulesExpresionTree.cs" />
+    <Compile Include="ITradeRulesModel.cs" />
+    <Compile Include="Solution\ITradeRulesSolution.cs" />
+    <Compile Include="Solution\ITradingRulesSolution.cs" />
+    <Compile Include="Symbols\Lag.cs" />
+    <Compile Include="Symbols\MACD.cs" />
+    <Compile Include="Symbols\MACDTreeNode.cs" />
+    <Compile Include="Symbols\Max.cs" />
+    <Compile Include="Symbols\Min.cs" />
+    <Compile Include="Evaluator\OnlineTradeRulesCalculator.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\HeuristicLab.Problems.TradeRules-1.0.cs" />
-    <Compile Include="RSI.cs" />
-    <Compile Include="TradeAnalysisProblem.cs" />
-    <Compile Include="TradeRulesAbstractProblem.cs" />
-    <Compile Include="TradeRulesProblem.cs" />
+    <Compile Include="Symbols\RSI.cs" />
+    <Compile Include="Evaluator\TradeRulesAnalysisEvaluator.cs" />
+    <Compile Include="Evaluator\TradeRulesAnalysisSingleObjectiveEvaluator.cs" />
+    <Compile Include="Evaluator\TradeRulesSingleObjectiveEvaluator.cs" />
+    <Compile Include="Problem\TradeAnalysisProblem.cs" />
+    <Compile Include="Problem\TradeRulesAbstractProblem.cs" />
+    <Compile Include="Problem\TradeRulesProblem.cs" />
+    <Compile Include="TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer.cs" />
+    <Compile Include="TradeRulesSingleObjectiveValidationBestSolutionAnalyzer.cs" />
+    <Compile Include="Solution\TradeRulesSolution.cs" />
+    <Compile Include="Solution\TradeRulesSolutionBase.cs" />
+    <Compile Include="Solution\TradingRulesSolution.cs" />
   </ItemGroup>
   <ItemGroup>
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/ITradeRulesModel.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/ITradeRulesModel.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/ITradeRulesModel.cs	(revision 9262)
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    public interface ITradeRulesModel : IDataAnalysisModel {
+    IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows);
+    ITradeRulesSolution CreateRegressionSolution(IRegressionProblemData problemData);
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Interpreter.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Interpreter.cs	(revision 9260)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Interpreter.cs	(revision 9262)
@@ -11,4 +11,6 @@
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
 using HeuristicLab.Problems.DataAnalysis;
+using System.Threading;
+using HeuristicLab.Problems.TradeRules.Symbols;
 
 namespace HeuristicLab.Problems.TradeRules
@@ -16,22 +18,25 @@
     [StorableClass]
     [Item("Interpreter", "Represents a grammar for Trading Problems")]
-    public sealed class Interpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter
+    public sealed class Interpreter : ParameterizedNamedItem, ITradeRulesExpresionTree
     {
         private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
         private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
+        private int initialTraining;
+        private int initialTest;
         [ThreadStatic]
-        private static double [] EMAValue;
+        private static Dictionary<ISymbolicExpressionTreeNode, double> signalCache;
         [ThreadStatic]
-        private static double inOut;
+        private static Dictionary<ISymbolicExpressionTreeNode, double> firstEMACache;
         [ThreadStatic]
-        private static double meanUp;
+        private static Dictionary<ISymbolicExpressionTreeNode, double> secondEMACache;
         [ThreadStatic]
-        private static double meanDown;
+        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIPositiveCache;
         [ThreadStatic]
-        private static double lastRSI;
-		
-		// [ThreadStatic]
-		// private Dictionary<Instruction, double> lastEMACache;
-		
+        private static Dictionary<ISymbolicExpressionTreeNode, double> RSINegativeCache;
+        [ThreadStatic]
+        private static Dictionary<ISymbolicExpressionTreeNode, double> RSICache;
+        [ThreadStatic]
+        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIOutputCache;
+
         #region private classes
         //This class manipulate the instructions of the stack
@@ -133,7 +138,4 @@
             public const byte Lag = 19;
             public const byte RSI = 20;
-            public const byte EMA = 21;
-            
-
         }
         #endregion
@@ -165,5 +167,4 @@
       { typeof(MACD), OpCodes.MACD},
       { typeof(RSI), OpCodes.RSI},
-      { typeof(EMA), OpCodes.EMA},
       { typeof(Max), OpCodes.Max},
       { typeof(Min), OpCodes.Min},
@@ -251,5 +252,5 @@
                         if (row < integerValue)
                         {
-                            string variableName = dataset.GetValue(row, 2);
+                            string variableName = dataset.GetValue(row, 3);
                             double inferiorValue = Convert.ToDouble(variableName);
                             return inferiorValue/(row+1);
@@ -257,63 +258,10 @@
                         else
                         {
-                            string variableName = dataset.GetValue(row, 2);
+                            string variableName = dataset.GetValue(row, 3);
                             double meanValue1 = Convert.ToDouble(variableName);
-                            string variableName2 = dataset.GetValue((row - integerValue), 2);
+                            string variableName2 = dataset.GetValue((row - integerValue), 3);
                             double meanValue2 = Convert.ToDouble(variableName2);
                             return (meanValue1 - meanValue2) / integerValue;
                         }
-                    }
-                case OpCodes.MACD:
-                    {                 
-                        /*double firstMean = Evaluate(dataset, ref row, state);
-                        double secondMean = Evaluate(dataset, ref row, state);
-                        double signal = Evaluate(dataset, ref row, state);
-                        double firstEMA = 0.0;
-                        double secondEMA = 0.0;
-                        double lastFirstEMA = 0.0;
-                        double lastSecondEMA = 0.0;
-                        double macd = 0.0;
-                        double firstFactor = 0.0;
-                        double signalValue = Double.NegativeInfinity;
-                        if (row == (firstMean - 1))
-                        {
-                            string variableName = dataset.GetValue(row, 2);
-                            double meanValue1 = Convert.ToDouble(variableName);
-                            firstEMA = meanValue1 / firstMean;
-                        }
-                        if (row == (secondMean-1))
-                        {
-                            string variableName = dataset.GetValue(row, 2);
-                            double meanValue2 = Convert.ToDouble(variableName);
-                            secondEMA = meanValue2 / secondMean;
-                        }
-                        string variableName2 = dataset.GetValue(row, 1);
-                        double intValue = Convert.ToDouble(variableName2);
-                        if (row > (firstMean-1))
-                        {
-                              firstFactor = 2 / (firstMean + 1);                          
-                              firstEMA = (intValue * firstFactor) + (lastFirstEMA * (1-firstFactor));
-                        }
-                            if (row > (secondMean-1))
-                            {
-                                double secondFactor = 2 / (secondMean + 1);
-                                secondEMA = (intValue * secondFactor) + (lastSecondEMA * (1 - secondFactor));      
-                            }
-                            lastFirstEMA = firstEMA;
-                            lastSecondEMA = secondEMA;
-                            macd = firstEMA - secondEMA;
-                        if ((row < (firstMean-1)) || (row < (secondMean-1))) return 0.0;
-                        else return macd;*/
-                        return 0.0;
-
-                        //macd = firstEMA - secondEMA;
-                        //if (row == Math.Max(firstMean, secondMean)) signalValue = macd;
-                        //if (row > firstMean && row > secondMean)
-                        //{
-                        //    double factor = 2 / (signal + 1);
-                        //    signalValue = (macd * factor) + (lastSignal * (1 - factor));
-                        //}
-                        //if (!Double.IsNegativeInfinity(signalValue)) lastSignal = signalValue;
-                        //return signalValue > macd ? 1.0 : -1.0;
                     }
                 case OpCodes.AND:
@@ -374,32 +322,4 @@
                         return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
                     }
-                case OpCodes.EMA:
-                    {
-                        //I assume you want to calculate the EMA as defined at http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
-						//for the mean value saved at position 1 of the dataset
-						//and timevalue specifies how many days you want to include in your EMA
-						double timeValue = (int)Evaluate(dataset, ref row, state);
-
-						// with caching
-						// if (lastEmaCache.ContainsKey(currentInst)
-						//   lastEma = lastEmaCache[currentInstr]
-						// else 
-						//   lastEma = 1;
-						
-						//get all mean values from row - timeValue up to the actual row
-						double[] meanValues = dataset.GetDoubleValues("insert variable name", Enumerable.Range(row - (int)timeValue, timeValue)).ToArray();
-
-						double EMA = meanValues[0];
-						double factor = 2.0 / (timeValue + 1.0);
-
-						for (int i = 1; i < timeValue; i++) {
-						  EMA = meanValues[i] * factor + (1 - factor) * EMA;
-						}
-						
-						// save in cache for next evaluation
-						// lastEmaCache[currentInstr] = EMA;
-						
-						return EMA;
-                    }
                 case OpCodes.Constant:
                     {
@@ -425,5 +345,5 @@
                         {
                             int position = row - i;
-                            string variableName = dataset.GetValue(position, 1);
+                            string variableName = dataset.GetValue(position, 2);
                             double intValue = Convert.ToDouble(variableName);
                             if (intValue>max) max = intValue;
@@ -440,5 +360,5 @@
                         {
                             int position = row - i;
-                            string variableName = dataset.GetValue(position, 1);
+                            string variableName = dataset.GetValue(position, 2);
                             double intValue = Convert.ToDouble(variableName);
                             if (intValue < min) min = intValue;
@@ -452,60 +372,160 @@
                         if (n>row) return 0;
                         int position = row - n;
-                        string variableName = dataset.GetValue(position, 1);
+                        string variableName = dataset.GetValue(position, 2);
                         double intValue = Convert.ToDouble(variableName);
                         return intValue;
                     }
+                case OpCodes.MACD:
+                    {
+                        var MACDNode = currentInstr.dynamicNode;
+                        //Taking the number of the days for each EMA
+                        double firstEMA = Evaluate(dataset, ref row, state);
+                        double secondEMA = Evaluate(dataset, ref row, state);
+                        double signal = Evaluate(dataset, ref row, state);
+
+                        //Calculating the factor for each EMA
+                        double factor = 2.0 / (firstEMA + 1.0);
+                        double factor2 = 2.0 / (secondEMA + 1.0);
+                        double factor3 = 2.0 / (signal + 1.0);
+
+                        //Initiation of the variables
+                        double firstElementEMA = -1000000;
+                        double secondElementEMA = -100000;
+                        double signalValue = -100000;
+                        double macd = 0;
+
+                        //Check if this MACD has previous values and retrieve them
+                        if (firstEMACache.ContainsKey(MACDNode)) firstElementEMA = firstEMACache[MACDNode];
+                        if (secondEMACache.ContainsKey(MACDNode)) secondElementEMA = secondEMACache[MACDNode];
+                        if (signalCache.ContainsKey(MACDNode)) signalValue = signalCache[MACDNode];
+
+                        //Calculate the first value in the training for the two EMAs and the signal.
+                        if (row <= initialTraining || row == initialTest)
+                        {
+                            double[] meanValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, (row + 1))).ToArray();
+                            firstElementEMA = meanValues[0];
+                            secondElementEMA = meanValues[0];
+                            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.
+                            for (int i = 1; i <= row; i++)
+                            {
+                                firstElementEMA = meanValues[i] * factor + (1 - factor) * firstElementEMA;
+                                secondElementEMA = meanValues[i] * factor2 + (1 - factor2) * secondElementEMA;
+                                if (i == max) signalValue = firstElementEMA - secondElementEMA;//First signal equals to macd.
+                                else if (i > max)//Calculation for the next signals
+                                {
+                                    macd = firstElementEMA - secondElementEMA;
+                                    signalValue = macd * factor3 + (1 - factor3) * signalValue;
+                                }
+                            }
+                        }
+                        else  //The rest of the rows are calculating with the standard EMA formula
+                        {
+                            //Retrieve the dataset values 
+                            string variableName = dataset.GetValue(row, 2);
+                            double meanValue1 = Convert.ToDouble(variableName);
+
+                            //Calculating EMA
+                            firstElementEMA = meanValue1 * factor + (1 - factor) * firstElementEMA;
+                            secondElementEMA = meanValue1 * factor2 + (1 - factor2) * secondElementEMA;
+
+                            //Calculating signal
+                            macd = firstElementEMA - secondElementEMA;
+                            signalValue = macd * factor3 + (1 - factor3) * signalValue;
+                        }
+
+                        //Save the values for the next iteration
+                        firstEMACache[MACDNode] = firstElementEMA;
+                        secondEMACache[MACDNode] = secondElementEMA;
+                        signalCache[MACDNode] = signalValue;
+
+                        macd = firstElementEMA - secondElementEMA;
+                        return macd > signalValue ? 1.0 : -1.0;
+                    }
                 case OpCodes.RSI:
-                    {
-                        /*
-                        double numberOfDays = Evaluate(dataset, ref row, state);
-                        double todayRSI=0.0;
-                        if (numberOfDays > row) return 0.0;
-                        else
-                        {
-                            double addUp = 0;
-                            double addDown = 0;
-                            double change=0;
-                            if (row == (numberOfDays))
-                            {
-                                for (int k = 1; k < (numberOfDays+1); k++)
-                                {
-                                    string variableName = dataset.GetValue(k, 1);
-                                    double intValue = Convert.ToDouble(variableName);
-                                    variableName = dataset.GetValue((k - 1), 1);
-                                    double intValue2 = Convert.ToDouble(variableName);
-                                     change = intValue - intValue2;
-                                    if (change > 0) addUp = addUp + change;
-                                    else addDown = addDown - change;
-                                  
-                                }
-                                meanUp = addUp / numberOfDays;
-                                meanDown = addDown / numberOfDays;
-                                if (meanDown != 0) todayRSI = 100 - (100 / (1 + (meanUp / meanDown)));
-                                else todayRSI = 100;
-                             }
-                            else
-                            {
-                                string variableName = dataset.GetValue(row, 1);
-                                double intValue = Convert.ToDouble(variableName);
-                                variableName = dataset.GetValue((row - 1), 1);
-                                double intValue2 = Convert.ToDouble(variableName);
-                                change = intValue - intValue2;
-
-                                addUp = meanUp * (numberOfDays - 1);
-                                addDown = meanDown * (numberOfDays - 1);
-                                if (change > 0) addUp = addUp + change;
-                                else addDown = addDown - change;
-                                meanUp = addUp / numberOfDays;
-                                meanDown = addDown / numberOfDays;
-                                if (meanDown != 0) todayRSI = 100 - (100 / (1 + (meanUp / meanDown)));
-                                else todayRSI = 100;
-                            }
-                        }
-                        if ((lastRSI < 70) && (todayRSI >= 70)) inOut = 1;
-                        else if((lastRSI > 30) && (todayRSI <= 30)) inOut=-1;
-                        lastRSI = todayRSI;*/
-                        return 0.0;
-                        
+                   {
+                       
+                       //Taking the number of the days for EMA
+                       double numberOfDays = Evaluate(dataset, ref row, state);
+
+                       //Calculate the factor for the EMA
+                       double factor = 1.0 / numberOfDays;
+
+                       double positiveEMA = 0;
+                       double negativeEMA = 0;
+                       double yesterdayRSI = double.NegativeInfinity;
+                       double todayRSI = double.NegativeInfinity;
+                       double outputRSI = double.NegativeInfinity;
+                       //Retrieve EMA values
+                       if (RSIPositiveCache.ContainsKey(currentInstr.dynamicNode)) positiveEMA = RSIPositiveCache[currentInstr.dynamicNode];
+                       if (RSINegativeCache.ContainsKey(currentInstr.dynamicNode)) negativeEMA = RSINegativeCache[currentInstr.dynamicNode];
+                       if (RSICache.ContainsKey(currentInstr.dynamicNode)) yesterdayRSI = RSICache[currentInstr.dynamicNode];
+                       if (RSIOutputCache.ContainsKey(currentInstr.dynamicNode)) outputRSI = RSIOutputCache[currentInstr.dynamicNode];
+
+                       if (row == initialTraining || row == initialTest)
+                       {
+                           double[] closeValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, (row + 1))).ToArray();
+                           outputRSI = -1.0;
+                           for (int i = 1; i <= row; i++)
+                           {
+                               if (numberOfDays>=i)
+                               {
+                                   if ((closeValues[i] - closeValues[i - 1]) > 0) positiveEMA = ((closeValues[i] - closeValues[i - 1])+positiveEMA);
+                                   else negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) + negativeEMA;
+                                   if (numberOfDays == i)
+                                   {
+                                       positiveEMA = positiveEMA/numberOfDays;
+                                       negativeEMA = negativeEMA / numberOfDays;
+                                       yesterdayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
+                                   }
+                               }else{
+                                    if ((closeValues[i] - closeValues[i - 1]) > 0)
+                                    {
+                                        positiveEMA = (closeValues[i]-closeValues[i-1]) * factor + (1 - factor) * positiveEMA;
+                                        negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
+                                    }
+                                    else
+                                    {
+                                        positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
+                                        negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) * factor + (1 - factor) * negativeEMA;
+                                    }
+                                   
+                                    todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
+
+                                    if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
+                                   else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
+                                   yesterdayRSI = todayRSI;
+                               }
+                           }
+                       }
+                       else
+                       {
+                           string todayCloseString = dataset.GetValue(row, 2);
+                           string yesterdayCloseString = dataset.GetValue((row - 1), 2);
+                           double todayClose = Convert.ToDouble(todayCloseString);
+                           double yesterdayClose = Convert.ToDouble(yesterdayCloseString);
+
+                           //Calculating EMA
+                           if ((todayClose - yesterdayClose) > 0)
+                           {
+                               positiveEMA = (todayClose-yesterdayClose) * factor + (1 - factor) * positiveEMA;
+                               negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
+                           }
+                           else
+                           {
+                               positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
+                               negativeEMA = Math.Abs(todayClose - yesterdayClose) * factor + (1 - factor) * negativeEMA;
+                           }
+                           todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
+                           if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
+                           else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
+                       }
+                       
+                       //Save positive and negative EMA for the next iteration
+                       RSIPositiveCache[currentInstr.dynamicNode] = positiveEMA;
+                       RSINegativeCache[currentInstr.dynamicNode] = negativeEMA;
+                       RSICache[currentInstr.dynamicNode] = todayRSI;
+                       RSIOutputCache[currentInstr.dynamicNode] = outputRSI;   
+                       
+                       return outputRSI;
                     }
                 
@@ -553,10 +573,30 @@
                 Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
         }
-        
+        public void setInitialTraining(int initialTraining)
+        {
+            this.initialTraining = initialTraining;
+        }
+
+        public void setInitialTest(int initialTest)
+        {
+            this.initialTest = initialTest;
+        }
+
+        public void clearVariables()
+        {
+            signalCache.Clear();
+            firstEMACache.Clear();
+            secondEMACache.Clear();
+            RSIPositiveCache.Clear();
+            RSINegativeCache.Clear();
+            RSICache.Clear();
+            RSIOutputCache.Clear();
+        }
+
         //Take the symbolic expression values of the tree
         public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows)
         {
             if (CheckExpressionsWithIntervalArithmetic.Value)
-                throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+            throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
             EvaluatedSolutions.Value++; // increment the evaluated solutions counter
             var compiler = new SymbolicExpressionTreeCompiler();
@@ -572,24 +612,28 @@
                     code[i] = instr;
                 }
-                else if (instr.opCode == OpCodes.EMA)
-                {
-                    instr.iArg0 = EMAValue;
+            }
+
+
+            if (signalCache == null) signalCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (firstEMACache == null) firstEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (secondEMACache == null) secondEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (RSIPositiveCache == null) RSIPositiveCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (RSINegativeCache == null) RSINegativeCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (RSICache == null) RSICache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+            if (RSIOutputCache == null) RSIOutputCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
+                                 
+                                       
+                                        var state = new InterpreterState(code, necessaryArgStackSize);
+                                        //Evaluate each row of the datase
+                                        foreach (var rowEnum in rows)
+                                        {
+                                            int row = rowEnum;
+                                            state.Reset();
+                                            if (row < initialTraining) yield return -1;
+                                            else yield return Evaluate(dataset, ref row, state);
+                                        }
                 }
-            }
-			
-			// with caching
-			// if (lastEmaCache == null) lastEmaCache = new Dictionary<Instruction, double>();
-			// else lastEmaCache.Clear();
-			
-            var state = new InterpreterState(code, necessaryArgStackSize);
-            //Evaluate each row of the datase
-            foreach (var rowEnum in rows)
-            {
-                int row = rowEnum;
-                state.Reset();
-                yield return Evaluate(dataset, ref row, state);
-            }
         }
 
     }
-}
+
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeAnalysisProblem.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeAnalysisProblem.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeAnalysisProblem.cs	(revision 9262)
@@ -0,0 +1,390 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.Instances;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    public abstract class TradeAnalysisProblem<T, U, V> : HeuristicOptimizationProblem<U, V>, IDataAnalysisProblem<T>, ISymbolicDataAnalysisProblem, IStorableContent,
+      IProblemInstanceConsumer<T>, IProblemInstanceExporter<T>
+        where T : class, IDataAnalysisProblemData
+        where U : class, ISymbolicDataAnalysisEvaluator<T>
+        where V : class, ISymbolicDataAnalysisSolutionCreator
+    {
+
+        #region parameter names & descriptions
+        private const string ProblemDataParameterName = "ProblemData";
+        private const string SymbolicExpressionTreeGrammarParameterName = "SymbolicExpressionTreeGrammar";
+        private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+        private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
+        private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
+        private const string MaximumFunctionDefinitionsParameterName = "MaximumFunctionDefinitions";
+        private const string MaximumFunctionArgumentsParameterName = "MaximumFunctionArguments";
+        private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+        private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
+        private const string ValidationPartitionParameterName = "ValidationPartition";
+
+        private const string ProblemDataParameterDescription = "";
+        private const string SymbolicExpressionTreeGrammarParameterDescription = "The grammar that should be used for symbolic expression tree.";
+        private const string SymoblicExpressionTreeInterpreterParameterDescription = "The interpreter that should be used to evaluate the symbolic expression tree.";
+        private const string MaximumSymbolicExpressionTreeDepthParameterDescription = "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.";
+        private const string MaximumSymbolicExpressionTreeLengthParameterDescription = "Maximal length of the symbolic expression.";
+        private const string MaximumFunctionDefinitionsParameterDescription = "Maximal number of automatically defined functions";
+        private const string MaximumFunctionArgumentsParameterDescription = "Maximal number of arguments of automatically defined functions.";
+        private const string RelativeNumberOfEvaluatedSamplesParameterDescription = "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation.";
+        private const string FitnessCalculationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to calculate the fitness of an individual.";
+        private const string ValidationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to select the best model from (optional).";
+        #endregion
+
+        #region parameter properties
+        IParameter IDataAnalysisProblem.ProblemDataParameter
+        {
+            get { return ProblemDataParameter; }
+        }
+        public IValueParameter<T> ProblemDataParameter
+        {
+            get { return (IValueParameter<T>)Parameters[ProblemDataParameterName]; }
+        }
+        public IValueParameter<ISymbolicDataAnalysisGrammar> SymbolicExpressionTreeGrammarParameter
+        {
+            get { return (IValueParameter<ISymbolicDataAnalysisGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; }
+        }
+        public IValueParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter
+        {
+            get { return (IValueParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+        }
+        public IFixedValueParameter<IntValue> MaximumSymbolicExpressionTreeDepthParameter
+        {
+            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeDepthParameterName]; }
+        }
+        public IFixedValueParameter<IntValue> MaximumSymbolicExpressionTreeLengthParameter
+        {
+            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeLengthParameterName]; }
+        }
+        public IFixedValueParameter<IntValue> MaximumFunctionDefinitionsParameter
+        {
+            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumFunctionDefinitionsParameterName]; }
+        }
+        public IFixedValueParameter<IntValue> MaximumFunctionArgumentsParameter
+        {
+            get { return (IFixedValueParameter<IntValue>)Parameters[MaximumFunctionArgumentsParameterName]; }
+        }
+        public IFixedValueParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter
+        {
+            get { return (IFixedValueParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+        }
+        public IFixedValueParameter<IntRange> FitnessCalculationPartitionParameter
+        {
+            get { return (IFixedValueParameter<IntRange>)Parameters[FitnessCalculationPartitionParameterName]; }
+        }
+        public IFixedValueParameter<IntRange> ValidationPartitionParameter
+        {
+            get { return (IFixedValueParameter<IntRange>)Parameters[ValidationPartitionParameterName]; }
+        }
+        #endregion
+
+        #region properties
+        public string Filename { get; set; }
+        public static new Image StaticItemImage { get { return VSImageLibrary.Type; } }
+
+        IDataAnalysisProblemData IDataAnalysisProblem.ProblemData
+        {
+            get { return ProblemData; }
+        }
+        public T ProblemData
+        {
+            get { return ProblemDataParameter.Value; }
+            set { ProblemDataParameter.Value = value; }
+        }
+
+        public ISymbolicDataAnalysisGrammar SymbolicExpressionTreeGrammar
+        {
+            get { return SymbolicExpressionTreeGrammarParameter.Value; }
+            set { SymbolicExpressionTreeGrammarParameter.Value = value; }
+        }
+        public ISymbolicDataAnalysisExpressionTreeInterpreter SymbolicExpressionTreeInterpreter
+        {
+            get { return SymbolicExpressionTreeInterpreterParameter.Value; }
+            set { SymbolicExpressionTreeInterpreterParameter.Value = value; }
+        }
+
+        public IntValue MaximumSymbolicExpressionTreeDepth
+        {
+            get { return MaximumSymbolicExpressionTreeDepthParameter.Value; }
+        }
+        public IntValue MaximumSymbolicExpressionTreeLength
+        {
+            get { return MaximumSymbolicExpressionTreeLengthParameter.Value; }
+        }
+        public IntValue MaximumFunctionDefinitions
+        {
+            get { return MaximumFunctionDefinitionsParameter.Value; }
+        }
+        public IntValue MaximumFunctionArguments
+        {
+            get { return MaximumFunctionArgumentsParameter.Value; }
+        }
+        public PercentValue RelativeNumberOfEvaluatedSamples
+        {
+            get { return RelativeNumberOfEvaluatedSamplesParameter.Value; }
+        }
+
+        public IntRange FitnessCalculationPartition
+        {
+            get { return FitnessCalculationPartitionParameter.Value; }
+        }
+        public IntRange ValidationPartition
+        {
+            get { return ValidationPartitionParameter.Value; }
+        }
+        #endregion
+
+        [StorableConstructor]
+        protected TradeAnalysisProblem(bool deserializing) : base(deserializing) { }
+        [StorableHook(HookType.AfterDeserialization)]
+        private void AfterDeserialization()
+        {
+            RegisterEventHandlers();
+        }
+        protected TradeAnalysisProblem(TradeAnalysisProblem<T, U, V> original, Cloner cloner)
+            : base(original, cloner)
+        {
+            RegisterEventHandlers();
+        }
+
+        protected TradeAnalysisProblem(T problemData, U evaluator, V solutionCreator)
+            : base(evaluator, solutionCreator)
+        {
+            Parameters.Add(new ValueParameter<T>(ProblemDataParameterName, ProblemDataParameterDescription, problemData));
+            Parameters.Add(new ValueParameter<ISymbolicDataAnalysisGrammar>(SymbolicExpressionTreeGrammarParameterName, SymbolicExpressionTreeGrammarParameterDescription));
+            Parameters.Add(new ValueParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, SymoblicExpressionTreeInterpreterParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, MaximumSymbolicExpressionTreeDepthParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, MaximumSymbolicExpressionTreeLengthParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntValue>(MaximumFunctionDefinitionsParameterName, MaximumFunctionDefinitionsParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntValue>(MaximumFunctionArgumentsParameterName, MaximumFunctionArgumentsParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntRange>(FitnessCalculationPartitionParameterName, FitnessCalculationPartitionParameterDescription));
+            Parameters.Add(new FixedValueParameter<IntRange>(ValidationPartitionParameterName, ValidationPartitionParameterDescription));
+            Parameters.Add(new FixedValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, RelativeNumberOfEvaluatedSamplesParameterDescription, new PercentValue(1)));
+
+            SymbolicExpressionTreeInterpreterParameter.Hidden = true;
+            MaximumFunctionArgumentsParameter.Hidden = true;
+            MaximumFunctionDefinitionsParameter.Hidden = true;
+
+            SymbolicExpressionTreeGrammar = new Grammar();
+            SymbolicExpressionTreeInterpreter = new Interpreter();
+
+            FitnessCalculationPartition.Start = ProblemData.TrainingPartition.Start;
+            FitnessCalculationPartition.End = ProblemData.TrainingPartition.End;
+
+            InitializeOperators();
+
+            UpdateGrammar();
+            RegisterEventHandlers();
+        }
+
+        protected virtual void UpdateGrammar()
+        {
+            SymbolicExpressionTreeGrammar.MaximumFunctionArguments = MaximumFunctionArguments.Value;
+            SymbolicExpressionTreeGrammar.MaximumFunctionDefinitions = MaximumFunctionDefinitions.Value;
+            foreach (var varSymbol in SymbolicExpressionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Variable>())
+            {
+                if (!varSymbol.Fixed) varSymbol.VariableNames = ProblemData.AllowedInputVariables;
+            }
+            foreach (var varSymbol in SymbolicExpressionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.VariableCondition>())
+            {
+                if (!varSymbol.Fixed) varSymbol.VariableNames = ProblemData.AllowedInputVariables;
+            }
+        }
+
+        private void InitializeOperators()
+        {
+            Operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>());
+            Operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicDataAnalysisExpressionCrossover<T>>());
+            Operators.Add(new SymbolicExpressionSymbolFrequencyAnalyzer());
+            Operators.Add(new SymbolicDataAnalysisVariableFrequencyAnalyzer());
+            Operators.Add(new MinAverageMaxSymbolicExpressionTreeLengthAnalyzer());
+            Operators.Add(new SymbolicExpressionTreeLengthAnalyzer());
+            ParameterizeOperators();
+        }
+
+        #region events
+        private void RegisterEventHandlers()
+        {
+            ProblemDataParameter.ValueChanged += new EventHandler(ProblemDataParameter_ValueChanged);
+            ProblemDataParameter.Value.Changed += (object sender, EventArgs e) => OnProblemDataChanged();
+
+            SymbolicExpressionTreeGrammarParameter.ValueChanged += new EventHandler(SymbolicExpressionTreeGrammarParameter_ValueChanged);
+
+            MaximumFunctionArguments.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
+            MaximumFunctionDefinitions.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
+            MaximumSymbolicExpressionTreeDepth.ValueChanged += new EventHandler(MaximumSymbolicExpressionTreeDepth_ValueChanged);
+        }
+
+        private void ProblemDataParameter_ValueChanged(object sender, EventArgs e)
+        {
+            ValidationPartition.Start = 0;
+            ValidationPartition.End = 0;
+            ProblemDataParameter.Value.Changed += (object s, EventArgs args) => OnProblemDataChanged();
+            OnProblemDataChanged();
+        }
+
+        private void SymbolicExpressionTreeGrammarParameter_ValueChanged(object sender, EventArgs e)
+        {
+            UpdateGrammar();
+        }
+
+        private void ArchitectureParameterValue_ValueChanged(object sender, EventArgs e)
+        {
+            UpdateGrammar();
+        }
+
+        private void MaximumSymbolicExpressionTreeDepth_ValueChanged(object sender, EventArgs e)
+        {
+            if (MaximumSymbolicExpressionTreeDepth != null && MaximumSymbolicExpressionTreeDepth.Value < 3)
+                MaximumSymbolicExpressionTreeDepth.Value = 3;
+        }
+
+        protected override void OnSolutionCreatorChanged()
+        {
+            base.OnSolutionCreatorChanged();
+            SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged += new EventHandler(SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged);
+            ParameterizeOperators();
+        }
+
+        private void SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged(object sender, EventArgs e)
+        {
+            ParameterizeOperators();
+        }
+
+        protected override void OnEvaluatorChanged()
+        {
+            base.OnEvaluatorChanged();
+            ParameterizeOperators();
+        }
+
+        public event EventHandler ProblemDataChanged;
+        protected virtual void OnProblemDataChanged()
+        {
+            FitnessCalculationPartition.Start = ProblemData.TrainingPartition.Start;
+            FitnessCalculationPartition.End = ProblemData.TrainingPartition.End;
+
+            UpdateGrammar();
+            ParameterizeOperators();
+
+            var handler = ProblemDataChanged;
+            if (handler != null) handler(this, EventArgs.Empty);
+
+            OnReset();
+        }
+        #endregion
+
+        protected virtual void ParameterizeOperators()
+        {
+            var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators).ToList();
+
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeGrammarBasedOperator>())
+            {
+                op.SymbolicExpressionTreeGrammarParameter.ActualName = SymbolicExpressionTreeGrammarParameterName;
+            }
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeSizeConstraintOperator>())
+            {
+                op.MaximumSymbolicExpressionTreeDepthParameter.ActualName = MaximumSymbolicExpressionTreeDepthParameterName;
+                op.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameterName;
+            }
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>())
+            {
+                op.MaximumFunctionArgumentsParameter.ActualName = MaximumFunctionArgumentsParameterName;
+                op.MaximumFunctionDefinitionsParameter.ActualName = MaximumFunctionDefinitionsParameterName;
+            }
+            foreach (var op in operators.OfType<ISymbolicDataAnalysisEvaluator<T>>())
+            {
+                op.ProblemDataParameter.ActualName = ProblemDataParameterName;
+                op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+                op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
+                op.RelativeNumberOfEvaluatedSamplesParameter.ActualName = RelativeNumberOfEvaluatedSamplesParameter.Name;
+            }
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeCrossover>())
+            {
+                op.ParentsParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+                op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+            }
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeManipulator>())
+            {
+                op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+            }
+            foreach (var op in operators.OfType<ISymbolicExpressionTreeAnalyzer>())
+            {
+                op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+            }
+            foreach (var op in operators.OfType<ISymbolicDataAnalysisAnalyzer>())
+            {
+                op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+            }
+            foreach (var op in operators.OfType<ISymbolicDataAnalysisValidationAnalyzer<U, T>>())
+            {
+                op.RelativeNumberOfEvaluatedSamplesParameter.ActualName = RelativeNumberOfEvaluatedSamplesParameter.Name;
+                op.ValidationPartitionParameter.ActualName = ValidationPartitionParameter.Name;
+            }
+            foreach (var op in operators.OfType<ISymbolicDataAnalysisInterpreterOperator>())
+            {
+                op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameterName;
+            }
+            foreach (var op in operators.OfType<ISymbolicDataAnalysisExpressionCrossover<T>>())
+            {
+                op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameterName;
+                op.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
+                op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
+                op.RelativeNumberOfEvaluatedSamplesParameter.ActualName = RelativeNumberOfEvaluatedSamplesParameter.Name;
+                op.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
+            }
+        }
+
+        #region Import & Export
+        public void Load(T data)
+        {
+            Name = data.Name;
+            Description = data.Description;
+            ProblemData = data;
+            OnReset();
+        }
+
+        public T Export()
+        {
+            return ProblemData;
+        }
+        #endregion
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesAbstractProblem.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesAbstractProblem.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesAbstractProblem.cs	(revision 9262)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    public abstract class TradeRulesAbstractProblem<T, U, V> : TradeAnalysisProblem<T, U, V>, ISingleObjectiveHeuristicOptimizationProblem
+        where T : class,IDataAnalysisProblemData
+        where U : class, ISymbolicDataAnalysisSingleObjectiveEvaluator<T>
+        where V : class, ISymbolicDataAnalysisSolutionCreator
+    {
+        private const string MaximizationParameterName = "Maximization";
+        private const string BestKnownQualityParameterName = "BestKnownQuality";
+
+        #region parameter properties
+        public IFixedValueParameter<BoolValue> MaximizationParameter
+        {
+            get { return (IFixedValueParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+        }
+        IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter
+        {
+            get { return MaximizationParameter; }
+        }
+        public IFixedValueParameter<DoubleValue> BestKnownQualityParameter
+        {
+            get { return (IFixedValueParameter<DoubleValue>)Parameters[BestKnownQualityParameterName]; }
+        }
+        IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter
+        {
+            get { return BestKnownQualityParameter; }
+        }
+        #endregion
+
+        #region properties
+        public BoolValue Maximization
+        {
+            get { return MaximizationParameter.Value; }
+        }
+        public DoubleValue BestKnownQuality
+        {
+            get { return BestKnownQualityParameter.Value; }
+        }
+        ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator
+        {
+            get { return Evaluator; }
+        }
+        #endregion
+
+        [StorableConstructor]
+        protected TradeRulesAbstractProblem(bool deserializing) : base(deserializing) { }
+        protected TradeRulesAbstractProblem(TradeRulesAbstractProblem<T, U, V> original, Cloner cloner)
+            : base(original, cloner)
+        {
+            RegisterEventHandler();
+            MaximizationParameter.Hidden = true;
+        }
+
+        public TradeRulesAbstractProblem(T problemData, U evaluator, V solutionCreator)
+            : base(problemData, evaluator, solutionCreator)
+        {
+            Parameters.Add(new FixedValueParameter<BoolValue>(MaximizationParameterName, "Set to false if the problem should be minimized."));
+            Parameters.Add(new FixedValueParameter<DoubleValue>(BestKnownQualityParameterName, "The quality of the best known solution of this problem."));
+
+            MaximizationParameter.Hidden = true;
+            InitializeOperators();
+            RegisterEventHandler();
+        }
+
+        [StorableHook(HookType.AfterDeserialization)]
+        private void AfterDeserialization()
+        {
+            RegisterEventHandler();
+        }
+
+        private void InitializeOperators()
+        {
+            Operators.Add(new SymbolicDataAnalysisAlleleFrequencyAnalyzer());
+            ParameterizeOperators();
+        }
+
+        private void RegisterEventHandler()
+        {
+            Evaluator.QualityParameter.ActualNameChanged += new EventHandler(QualityParameter_ActualNameChanged);
+        }
+
+        protected override void OnEvaluatorChanged()
+        {
+            base.OnEvaluatorChanged();
+            Evaluator.QualityParameter.ActualNameChanged += new EventHandler(QualityParameter_ActualNameChanged);
+            Maximization.Value = base.Evaluator.Maximization;
+            ParameterizeOperators();
+        }
+
+        private void QualityParameter_ActualNameChanged(object sender, EventArgs e)
+        {
+            ParameterizeOperators();
+        }
+
+        protected override void ParameterizeOperators()
+        {
+            base.ParameterizeOperators();
+
+            foreach (var op in Operators.OfType<ISymbolicDataAnalysisSingleObjectiveAnalyzer>())
+            {
+                op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+                op.MaximizationParameter.ActualName = MaximizationParameterName;
+            }
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesProblem.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesProblem.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Problem/TradeRulesProblem.cs	(revision 9262)
@@ -0,0 +1,164 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 
+ 
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [Item("TradeRules", "Represents a trade rules in a symbolic regression problem.")]
+    [StorableClass]
+    [Creatable("Problems")]
+    public class TradeRulesProblem : TradeRulesAbstractProblem<IRegressionProblemData, ISymbolicRegressionSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, IRegressionProblem
+    {
+        private const double PunishmentFactor = 10;
+        private const int InitialMaximumTreeDepth = 8;
+        private const int InitialMaximumTreeLength = 25;
+        private const string EstimationLimitsParameterName = "EstimationLimits";
+        private const string EstimationLimitsParameterDescription = "The limits for the estimated value that can be returned by the symbolic regression model.";
+
+        #region parameter properties
+        public IFixedValueParameter<DoubleLimit> EstimationLimitsParameter
+        {
+            get { return (IFixedValueParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+        }
+        #endregion
+        #region properties
+        public DoubleLimit EstimationLimits
+        {
+            get { return EstimationLimitsParameter.Value; }
+        }
+        #endregion
+        [StorableConstructor]
+        protected TradeRulesProblem(bool deserializing) : base(deserializing) { }
+        protected TradeRulesProblem(TradeRulesProblem original, Cloner cloner)
+            : base(original, cloner)
+        {
+            RegisterEventHandlers();
+        }
+        public override IDeepCloneable Clone(Cloner cloner) { return new TradeRulesProblem(this, cloner); }
+
+        public TradeRulesProblem()
+            : base(new RegressionProblemData(), new EvaluatorTradeRules(), new SymbolicDataAnalysisExpressionTreeCreator())
+        {
+            Parameters.Add(new FixedValueParameter<DoubleLimit>(EstimationLimitsParameterName, EstimationLimitsParameterDescription));
+
+            EstimationLimitsParameter.Hidden = true;
+
+            Maximization.Value = true;
+            MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
+            MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
+
+            RegisterEventHandlers();
+            ConfigureGrammarSymbols();
+            InitializeOperators();
+            UpdateEstimationLimits();
+        }
+
+        [StorableHook(HookType.AfterDeserialization)]
+        private void AfterDeserialization()
+        {
+            RegisterEventHandlers();
+            // compatibility
+            bool changed = false;
+            if (!Operators.OfType<SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer>().Any())
+            {
+                Operators.Add(new SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer());
+                changed = true;
+            }
+            if (!Operators.OfType<SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer>().Any())
+            {
+                Operators.Add(new SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer());
+                changed = true;
+            }
+            if (changed)
+            {
+                ParameterizeOperators();
+            }
+        }
+
+        private void RegisterEventHandlers()
+        {
+            SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
+        }
+
+        private void ConfigureGrammarSymbols()
+        {
+            var grammar = SymbolicExpressionTreeGrammar as Grammar;
+            if (grammar != null) grammar.ConfigureAsDefaultRegressionGrammar();
+        }
+
+        private void InitializeOperators()
+        {
+            Operators.Add(new TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer());
+            Operators.Add(new TradeRulesSingleObjectiveValidationBestSolutionAnalyzer());
+            Operators.Add(new SymbolicRegressionSingleObjectiveOverfittingAnalyzer());
+            Operators.Add(new SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer());
+            Operators.Add(new SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer());
+
+            ParameterizeOperators();
+        }
+
+        private void UpdateEstimationLimits()
+        {
+            if (ProblemData.TrainingIndices.Any())
+            {
+                var targetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
+                var mean = targetValues.Average();
+                var range = targetValues.Max() - targetValues.Min();
+                EstimationLimits.Upper = mean + PunishmentFactor * range;
+                EstimationLimits.Lower = mean - PunishmentFactor * range;
+            }
+            else
+            {
+                EstimationLimits.Upper = double.MaxValue;
+                EstimationLimits.Lower = double.MinValue;
+            }
+        }
+
+        protected override void OnProblemDataChanged()
+        {
+            base.OnProblemDataChanged();
+            UpdateEstimationLimits();
+        }
+
+        protected override void ParameterizeOperators()
+        {
+            base.ParameterizeOperators();
+            if (Parameters.ContainsKey(EstimationLimitsParameterName))
+            {
+                var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
+                foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>())
+                {
+                    op.EstimationLimitsParameter.ActualName = EstimationLimitsParameter.Name;
+                }
+            }
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradeRulesSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradeRulesSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradeRulesSolution.cs	(revision 9262)
@@ -0,0 +1,25 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    public interface ITradeRulesSolution : IDataAnalysisSolution
+    {
+        new ISymbolicRegressionModel Model { get; }
+        new IRegressionProblemData ProblemData { get; set; }
+
+        IEnumerable<double> EstimatedTestValues { get; }
+        IEnumerable<double> EstimatedTrainingValues { get; }
+        IEnumerable<double> EstimatedValues { get; }
+        IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+        
+        double TestCash { get; }
+        double TrainingCash { get; }      
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradingRulesSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradingRulesSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/ITradingRulesSolution.cs	(revision 9262)
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    public interface ITradingRulesSolution : ITradeRulesSolution, ISymbolicDataAnalysisSolution {
+    new ISymbolicRegressionModel Model { get; }
+  }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolution.cs	(revision 9262)
@@ -0,0 +1,70 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    /// <summary>
+    /// Represents a regression data analysis solution
+    /// </summary>
+    [StorableClass]
+    public abstract class TradeRulesSolution : TradeRulesSolutionBase
+    {
+       protected readonly Dictionary<int, double> evaluationCache;
+
+    [StorableConstructor]
+    protected TradeRulesSolution(bool deserializing)
+      : base(deserializing) {
+      evaluationCache = new Dictionary<int, double>();
+    }
+    protected TradeRulesSolution(TradeRulesSolution original, Cloner cloner)
+      : base(original, cloner) {
+      evaluationCache = new Dictionary<int, double>(original.evaluationCache);
+    }
+    protected TradeRulesSolution(IRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
+    }
+
+    protected override void RecalculateResults() {
+      CalculateResults();
+    }
+
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedValues(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
+    }
+
+    protected override void OnProblemDataChanged() {
+      evaluationCache.Clear();
+      base.OnProblemDataChanged();
+    }
+
+    protected override void OnModelChanged() {
+      evaluationCache.Clear();
+      base.OnModelChanged();
+    }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolutionBase.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolutionBase.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradeRulesSolutionBase.cs	(revision 9262)
@@ -0,0 +1,235 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+      [StorableClass]
+    public abstract class TradeRulesSolutionBase : DataAnalysisSolution, IRegressionSolution
+    {
+        private const string TrainingCashResultName = "Cash after the operation (training)";
+        private const string TestCashResultName = "Cash after the operation (test)";
+        private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+        private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+        private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+        private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+        private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+        private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
+        private const string TrainingRelativeErrorResultName = "Average relative error (training)";
+        private const string TestRelativeErrorResultName = "Average relative error (test)";
+        private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+        private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+        private const string TrainingMeanErrorResultName = "Mean error (training)";
+        private const string TestMeanErrorResultName = "Mean error (test)";
+
+        public new IRegressionModel Model
+        {
+            get { return (IRegressionModel)base.Model; }
+            protected set { base.Model = value; }
+        }
+
+        public new IRegressionProblemData ProblemData
+        {
+            get { return (IRegressionProblemData)base.ProblemData; }
+            set { base.ProblemData = value; }
+        }
+
+        public abstract IEnumerable<double> EstimatedValues { get; }
+        public abstract IEnumerable<double> EstimatedTrainingValues { get; }
+        public abstract IEnumerable<double> EstimatedTestValues { get; }
+        public abstract IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+
+
+        #region Results
+        public double TrainingCash
+        {
+            get { return ((DoubleValue)this[TrainingCashResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingCashResultName].Value).Value = value; }
+        }
+        public double TestCash
+        {
+            get { return ((DoubleValue)this[TestCashResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestCashResultName].Value).Value = value; }
+        }
+        public double TrainingMeanSquaredError
+        {
+            get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+        }
+        public double TestMeanSquaredError
+        {
+            get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+        }
+        public double TrainingMeanAbsoluteError
+        {
+            get { return ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value = value; }
+        }
+        public double TestMeanAbsoluteError
+        {
+            get { return ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value = value; }
+        }
+        public double TrainingRSquared
+        {
+            get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
+        }
+        public double TestRSquared
+        {
+            get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
+        }
+        public double TrainingRelativeError
+        {
+            get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
+        }
+        public double TestRelativeError
+        {
+            get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
+        }
+        public double TrainingNormalizedMeanSquaredError
+        {
+            get { return ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+        }
+        public double TestNormalizedMeanSquaredError
+        {
+            get { return ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+        }
+        public double TrainingMeanError
+        {
+            get { return ((DoubleValue)this[TrainingMeanErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TrainingMeanErrorResultName].Value).Value = value; }
+        }
+        public double TestMeanError
+        {
+            get { return ((DoubleValue)this[TestMeanErrorResultName].Value).Value; }
+            private set { ((DoubleValue)this[TestMeanErrorResultName].Value).Value = value; }
+        }
+        #endregion
+
+
+          [StorableConstructor]
+    protected TradeRulesSolutionBase(bool deserializing) : base(deserializing) { }
+    protected TradeRulesSolutionBase(TradeRulesSolutionBase original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    protected TradeRulesSolutionBase(IRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+          Add(new Result(TrainingCashResultName, "Cash obtained after training period in the stock market", new DoubleValue()));
+      Add(new Result(TestCashResultName, "Cash obtained after test period in the stock market", new DoubleValue()));
+      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
+      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
+      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new PercentValue()));
+      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new PercentValue()));
+      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization()
+    {
+        // BackwardsCompatibility3.4
+
+        #region Backwards compatible code, remove with 3.5
+
+        if (!ContainsKey(TrainingMeanAbsoluteErrorResultName))
+        {
+            OnlineCalculatorError errorState;
+            Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+            double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
+            TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+        }
+
+        if (!ContainsKey(TestMeanAbsoluteErrorResultName))
+        {
+            OnlineCalculatorError errorState;
+            Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
+            double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
+            TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+        }
+
+        if (!ContainsKey(TrainingMeanErrorResultName))
+        {
+            OnlineCalculatorError errorState;
+            Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
+            double trainingME = OnlineMeanErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
+            TrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+        }
+        if (!ContainsKey(TestMeanErrorResultName))
+        {
+            OnlineCalculatorError errorState;
+            Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
+            double testME = OnlineMeanErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
+            TestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+        }
+        #endregion
+    }
+
+
+    protected void CalculateResults()
+    {
+        IEnumerable<double> estimatedValues = EstimatedValues;
+        IEnumerable<double> estimatedTrainingValues = EstimatedTrainingValues; // cache values
+        IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
+        IEnumerable<double> estimatedTestValues = EstimatedTestValues; // cache values
+        IEnumerable<double> originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices);
+
+        OnlineCalculatorError errorState;
+        double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+        double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+
+        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+
+        double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+        double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+
+        double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+        double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+
+        double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+        double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+
+        double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+        TrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+        double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+        TestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+
+        double trainingCTR = OnlineTradeRulesCalculator.Calculate(estimatedTrainingValues, ProblemData, ProblemData.TrainingIndices);
+        TrainingCash = trainingCTR;
+        double testCTR = OnlineTradeRulesCalculator.Calculate(estimatedTestValues, ProblemData, ProblemData.TestIndices);
+        TestCash = testCTR;
+    }
+
+
+   }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradingRulesSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradingRulesSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Solution/TradingRulesSolution.cs	(revision 9262)
@@ -0,0 +1,62 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Data;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    [Item(Name = "TradingRulesSolution", Description = "Represents a trade rules solution (model + data) and attributes of the solution like cash earned")]
+    public sealed class TradingRulesSolution : TradeRulesSolution, ISymbolicRegressionSolution 
+    {
+    private const string ModelLengthResultName = "Model Length";
+    private const string ModelDepthResultName = "Model Depth";
+
+    public new ISymbolicRegressionModel Model {
+      get { return (ISymbolicRegressionModel)base.Model; }
+      set { base.Model = value; }
+    }
+    ISymbolicDataAnalysisModel ISymbolicDataAnalysisSolution.Model {
+      get { return (ISymbolicDataAnalysisModel)base.Model; }
+    }
+    public int ModelLength {
+      get { return ((IntValue)this[ModelLengthResultName].Value).Value; }
+      private set { ((IntValue)this[ModelLengthResultName].Value).Value = value; }
+    }
+
+    public int ModelDepth {
+      get { return ((IntValue)this[ModelDepthResultName].Value).Value; }
+      private set { ((IntValue)this[ModelDepthResultName].Value).Value = value; }
+    }
+
+    [StorableConstructor]
+    private TradingRulesSolution(bool deserializing) : base(deserializing) { }
+    private TradingRulesSolution(TradingRulesSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public TradingRulesSolution(ISymbolicRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue()));
+      Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue()));
+      RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+        return new TradingRulesSolution(this, cloner);
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      ModelLength = Model.SymbolicExpressionTree.Length;
+      ModelDepth = Model.SymbolicExpressionTree.Depth;
+    }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/AverageTrade.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/AverageTrade.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/AverageTrade.cs	(revision 9262)
@@ -0,0 +1,37 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    [Item("Average", "Symbol that represents the average (arithmetic mean) function.")]
+    public class AverageTrade : Symbol
+    {
+        private const int minimumArity = 1;
+        private const int maximumArity = 1;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+        [StorableConstructor]
+        private AverageTrade(bool deserializing) : base(deserializing) { }
+        private AverageTrade(AverageTrade original, Cloner cloner) : base(original, cloner) { }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new AverageTrade(this, cloner);
+        }
+        public AverageTrade() : base("AverageTrade", "Symbol that represents the average (arithmetic mean) function.") { }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstant.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstant.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstant.cs	(revision 9262)
@@ -0,0 +1,50 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    [Item("BoolConstant", "Represents a BoolConstant value.")]
+    public sealed class BoolConstant : Symbol
+    {
+        private const int minimumArity = 0;
+        private const int maximumArity = 0;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+
+        [StorableConstructor]
+        private BoolConstant(bool deserializing) : base(deserializing) { }
+        private BoolConstant(BoolConstant original, Cloner cloner)
+            : base(original, cloner)
+        {
+        }
+        public BoolConstant()
+            : base("BoolConstant", "Represents a BoolConstant value.")
+        {
+        }
+
+        public override ISymbolicExpressionTreeNode CreateTreeNode()
+        {
+            return new BoolConstantTreeNode(this);
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new BoolConstant(this, cloner);
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstantTreeNode.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstantTreeNode.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/BoolConstantTreeNode.cs	(revision 9262)
@@ -0,0 +1,59 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    public sealed class BoolConstantTreeNode : SymbolicExpressionTreeTerminalNode
+    {
+
+      public new BoolConstant Symbol {
+      get { return (BoolConstant)base.Symbol; }
+    }
+
+    private double BoolConstantValue;
+    [Storable]
+    public double Value {
+      get { return BoolConstantValue; }
+      set { BoolConstantValue = value; }
+    }
+
+    [StorableConstructor]
+    private BoolConstantTreeNode(bool deserializing) : base(deserializing) { }
+
+    private BoolConstantTreeNode(BoolConstantTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      BoolConstantValue = original.BoolConstantValue;
+    }
+
+    private BoolConstantTreeNode() : base() { }
+    public BoolConstantTreeNode(BoolConstant BoolConstantSymbol) : base(BoolConstantSymbol) { }
+
+    public override bool HasLocalParameters {
+      get {
+        return true;
+      }
+    }
+    public override void ResetLocalParameters(IRandom random) {
+      base.ResetLocalParameters(random);
+      if (random.Next(1) == 0) Value = -1;
+      else Value = 1;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolConstantTreeNode(this, cloner);
+    }
+
+    public override string ToString() {
+      return BoolConstantValue.ToString("E5");
+    }
+  }
+}
+
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantInt.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantInt.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantInt.cs	(revision 9262)
@@ -0,0 +1,50 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    [Item("ConstantInt", "Represents a ConstantInt value.")]
+    public sealed class ConstantInt : Symbol
+    {
+        private const int minimumArity = 0;
+        private const int maximumArity = 0;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+
+        [StorableConstructor]
+        private ConstantInt(bool deserializing) : base(deserializing) { }
+        private ConstantInt(ConstantInt original, Cloner cloner)
+            : base(original, cloner)
+        {
+        }
+        public ConstantInt()
+            : base("ConstantInt", "Represents a ConstantInt value.")
+        {
+        }
+
+        public override ISymbolicExpressionTreeNode CreateTreeNode()
+        {
+            return new ConstantIntTreeNode(this);
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new ConstantInt(this, cloner);
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantIntTreeNode.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantIntTreeNode.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ConstantIntTreeNode.cs	(revision 9262)
@@ -0,0 +1,66 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    public sealed class ConstantIntTreeNode : SymbolicExpressionTreeTerminalNode
+    {
+
+        public new ConstantInt Symbol
+        {
+            get { return (ConstantInt)base.Symbol; }
+        }
+
+        private double ConstantIntValue;
+        [Storable]
+        public double Value
+        {
+            get { return ConstantIntValue; }
+            set { ConstantIntValue = value; }
+        }
+
+        [StorableConstructor]
+        private ConstantIntTreeNode(bool deserializing) : base(deserializing) { }
+
+        private ConstantIntTreeNode(ConstantIntTreeNode original, Cloner cloner)
+            : base(original, cloner)
+        {
+            ConstantIntValue = original.ConstantIntValue;
+        }
+
+        private ConstantIntTreeNode() : base() { }
+        public ConstantIntTreeNode(ConstantInt ConstantIntSymbol) : base(ConstantIntSymbol) { }
+
+        public override bool HasLocalParameters
+        {
+            get
+            {
+                return true;
+            }
+        }
+        public override void ResetLocalParameters(IRandom random)
+        {
+            base.ResetLocalParameters(random);
+            
+            Value = random.Next(25)+1;
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new ConstantIntTreeNode(this, cloner);
+        }
+
+        public override string ToString()
+        {
+            return ConstantIntValue.ToString("E5");
+        }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ITradeRulesExpresionTree.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ITradeRulesExpresionTree.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/ITradeRulesExpresionTree.cs	(revision 9262)
@@ -0,0 +1,17 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    public interface ITradeRulesExpresionTree : ISymbolicDataAnalysisExpressionTreeInterpreter
+    {
+         void setInitialTraining(int initialTraining);
+         void setInitialTest(int initialTest);
+         void clearVariables();
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Lag.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Lag.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Lag.cs	(revision 9262)
@@ -0,0 +1,34 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class Lag : Symbol
+    {
+        private const int minimumArity = 1;
+        private const int maximumArity = 1;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+        [StorableConstructor]
+        private Lag(bool deserializing) : base(deserializing) { }
+        private Lag(Lag original, Cloner cloner) : base(original, cloner) { }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new Lag(this, cloner);
+        }
+        public Lag() : base("Lag", "Symbol that represents the Lag value in a time") { }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACD.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACD.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACD.cs	(revision 9262)
@@ -0,0 +1,52 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.TradeRules.Symbols;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [StorableClass]
+    [Item("MACD", "Symbol that represents the MACD indicator.")]
+    public sealed class MACD : Symbol
+    {
+        private const int minimumArity = 3;
+        private const int maximumArity = 3;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+       [StorableConstructor]
+        private MACD(bool deserializing) : base(deserializing) { }
+        private MACD(MACD original, Cloner cloner)
+            : base(original, cloner)
+        {
+        }
+        public MACD()
+            : base("MACD", "Represents a MACD indicator.")
+        {
+        }
+
+        public override ISymbolicExpressionTreeNode CreateTreeNode()
+        {
+            return new MACDTreeNode(this);
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new MACD(this, cloner);
+        }
+
+
+    }
+ }
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACDTreeNode.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACDTreeNode.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/MACDTreeNode.cs	(revision 9262)
@@ -0,0 +1,38 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules.Symbols
+{
+    public sealed class  MACDTreeNode : SymbolicExpressionTreeNode
+    {
+      public new MACD Symbol {
+      get { return (MACD)base.Symbol;}
+    }
+
+    [StorableConstructor]
+    private MACDTreeNode(bool deserializing) : base(deserializing) { }
+
+    private MACDTreeNode(MACDTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+      
+    }
+
+    public MACDTreeNode(MACD MACDSymbol) : base(MACDSymbol) { }
+
+    public override bool HasLocalParameters {
+      get {
+        return true;
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MACDTreeNode(this, cloner);
+    }
+
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Max.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Max.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Max.cs	(revision 9262)
@@ -0,0 +1,35 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class Max :Symbol
+    {
+        private const int minimumArity = 1;
+        private const int maximumArity = 1;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+        [StorableConstructor]
+        private Max(bool deserializing) : base(deserializing) { }
+        private Max(Max original, Cloner cloner) : base(original, cloner) { }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new Max(this, cloner);
+        }
+        public Max() : base("Max", "Symbol that represents the Max value in a time") { }
+    }
+ }
+
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Min.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Min.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/Min.cs	(revision 9262)
@@ -0,0 +1,34 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class Min : Symbol
+    {
+        private const int minimumArity = 1;
+        private const int maximumArity = 1;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+        [StorableConstructor]
+        private Min(bool deserializing) : base(deserializing) { }
+        private Min(Min original, Cloner cloner) : base(original, cloner) { }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new Min(this, cloner);
+        }
+        public Min() : base("Min", "Symbol that represents the Min value in a time") { }
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/RSI.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/RSI.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/Symbols/RSI.cs	(revision 9262)
@@ -0,0 +1,35 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class RSI: Symbol
+    {
+        private const int minimumArity = 1;
+        private const int maximumArity = 1;
+
+        public override int MinimumArity
+        {
+            get { return minimumArity; }
+        }
+        public override int MaximumArity
+        {
+            get { return maximumArity; }
+        }
+
+        [StorableConstructor]
+        private RSI(bool deserializing) : base(deserializing) { }
+        private RSI(RSI original, Cloner cloner) : base(original, cloner) { }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new RSI(this, cloner);
+        }
+        public RSI() : base("RSI", "Symbol that represents the RSI indicator.") { }
+    
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 9262)
@@ -0,0 +1,69 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Parameters;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [Item("TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic regression solution for single objective symbolic regression problems.")]
+    [StorableClass]
+    public sealed class TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicRegressionSolution>,
+  ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator 
+    {
+        private const string ProblemDataParameterName = "ProblemData";
+    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+    #region parameter properties
+    public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+    }
+    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public BoolValue ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer(TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
+      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(false)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TradeRulesSingleObjectiveTrainingBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
+      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScaling.Value)
+          SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      return new TradingRulesSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
+    }
+  }
+    }
+
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/TradeRulesSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 9262)
@@ -0,0 +1,61 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    [Item("TradeRulesSingleObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic regression solution for single objective symbolic regression problems.")]
+    [StorableClass]
+    public sealed class TradeRulesSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicRegressionSolution, ISymbolicRegressionSingleObjectiveEvaluator, IRegressionProblemData>,
+    ISymbolicDataAnalysisBoundedOperator
+    {
+         private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+
+    #region parameter properties
+    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public BoolValue ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private TradeRulesSingleObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private TradeRulesSingleObjectiveValidationBestSolutionAnalyzer(TradeRulesSingleObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public TradeRulesSingleObjectiveValidationBestSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
+      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(false)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+        return new TradeRulesSingleObjectiveValidationBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
+      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScaling.Value)
+        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      return new TradingRulesSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
+    }
+
+    }
+}
Index: branches/sluengo/HeuristicLab.Problems.TradeRules/TradeSolution.cs
===================================================================
--- branches/sluengo/HeuristicLab.Problems.TradeRules/TradeSolution.cs	(revision 9262)
+++ branches/sluengo/HeuristicLab.Problems.TradeRules/TradeSolution.cs	(revision 9262)
@@ -0,0 +1,11 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.Problems.TradeRules
+{
+    class TradeSolution
+    {
+    }
+}
