Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Views/3.3/ResultsView.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Views/3.3/ResultsView.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis.Views/3.3/ResultsView.cs	(revision 5305)
@@ -138,5 +138,5 @@
         rowIndex = 0;
         foreach (var evaluator in testEvaluators[targetVariable]) {
-          matrix[rowIndex++, columnIndex] = Math.Round(evaluator.Value);
+          matrix[rowIndex++, columnIndex] = Math.Round(evaluator.Value, 3);
         }
         columnIndex++;
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Evaluators/OnlineTheilsUStatisticEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Evaluators/OnlineTheilsUStatisticEvaluator.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Evaluators/OnlineTheilsUStatisticEvaluator.cs	(revision 5305)
@@ -14,4 +14,6 @@
     private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
     private double prevOriginal;
+    private int windowSize;
+    private Queue<double> movingAverageWindow;
 
     public double TheilsUStatistic {
@@ -21,5 +23,11 @@
     }
 
-    public OnlineTheilsUStatisticEvaluator() {
+    public OnlineTheilsUStatisticEvaluator()
+      : this(1) {
+    }
+
+    public OnlineTheilsUStatisticEvaluator(int movingAverageWindowSize) {
+      this.windowSize = movingAverageWindowSize;
+      movingAverageWindow = new Queue<double>(windowSize);
       squaredErrorMeanCalculator = new OnlineMeanAndVarianceCalculator();
       unbiasedEstimatorMeanCalculator = new OnlineMeanAndVarianceCalculator();
@@ -42,8 +50,25 @@
         squaredErrorMeanCalculator.Add(errorEstimatedChange * errorEstimatedChange);
 
-        // error of naive model y(t+1) = y(t)
-        double errorNoChange = (original - prevOriginal);
+        // calculate trend observed in the MA window
+        double d = CalculateTrend(movingAverageWindow);
+        
+        // shift window forward
+        if (movingAverageWindow.Count == windowSize) {
+          movingAverageWindow.Dequeue();
+        }
+        movingAverageWindow.Enqueue(original);
+
+        double errorNoChange = (original - prevOriginal * (1+d));
         unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
       }
+    }
+
+    private double CalculateTrend(Queue<double> movingAverageWindow) {
+      double[] xs = movingAverageWindow.ToArray();
+      double sum = 0.0;
+      for (int i = 0; i < xs.Length - 1; i++) {
+        sum += (xs[i + 1] - xs[i]) / xs[i];
+      }
+      return sum / xs.Length;
     }
 
@@ -52,4 +77,5 @@
       squaredErrorMeanCalculator.Reset();
       unbiasedEstimatorMeanCalculator.Reset();
+      movingAverageWindow.Clear();
     }
 
@@ -60,4 +86,5 @@
     public void StartNewPredictionWindow(double referenceOriginalValue) {
       prevOriginal = referenceOriginalValue;
+      movingAverageWindow.Enqueue(referenceOriginalValue);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis-3.3.csproj
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis-3.3.csproj	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis-3.3.csproj	(revision 5305)
@@ -148,4 +148,5 @@
     <Compile Include="HeuristicLabProblemsDataAnalysisMultiVariateTimeSeriesPrognosisPlugin.cs" />
     <Compile Include="Symbolic\Analyzer\ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer.cs" />
+    <Compile Include="Symbolic\Evaluators\SymbolicTimeSeriesPrognosisNormalizedMseEvaluator.cs" />
     <Compile Include="Symbolic\Evaluators\SymbolicTimeSeriesPrognosisScaledNormalizedFractionalDistanceEvaluator.cs" />
     <Compile Include="Symbolic\Evaluators\SymbolicTimeSeriesPrognosisEvaluator.cs" />
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Analyzer/ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Analyzer/ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Analyzer/ValidationBestScaledSymbolicTimeSeriesPrognosisSolutionAnalyzer.cs	(revision 5305)
@@ -53,4 +53,6 @@
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
     private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string EvaluatorParameterName = "Evaluator";
+    private const string MaximizationParameterName = "Maximization";
     private const string ProblemDataParameterName = "ProblemData";
     private const string ValidationSamplesStartParameterName = "SamplesStart";
@@ -60,58 +62,28 @@
     private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
     private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
-    private const string PredictionHorizonParameterName = "PredictionHorizon";
+    private const string ValidationPredictionHorizonParameterName = "ValidationPredictionHorizon";
+    private const string ModelPredictionHorizonParameterName = "ModelPredictionHorizon";
     private const string ConditionVariableParameterName = "ConditionVariableName";
-    private const string AlphaParameterName = "Alpha";
-    private const string BetaParameterName = "Beta";
+    private const string ResultsParameterName = "Results";
+    private const string VariableFrequenciesParameterName = "VariableFrequencies";
+    private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+
     private const string BestSolutionParameterName = "Best solution (validation)";
     private const string BestSolutionQualityParameterName = "Best solution quality (validation)";
     private const string CurrentBestValidationQualityParameterName = "Current best validation quality";
     private const string BestSolutionQualityValuesParameterName = "Validation Quality";
-    private const string ResultsParameterName = "Results";
-    private const string VariableFrequenciesParameterName = "VariableFrequencies";
     private const string BestKnownQualityParameterName = "BestKnownQuality";
     private const string GenerationsParameterName = "Generations";
 
-    private const string TrainingMeanSquaredErrorQualityParameterName = "Mean squared error (training)";
-    private const string MinTrainingMeanSquaredErrorQualityParameterName = "Min mean squared error (training)";
-    private const string MaxTrainingMeanSquaredErrorQualityParameterName = "Max mean squared error (training)";
-    private const string AverageTrainingMeanSquaredErrorQualityParameterName = "Average mean squared error (training)";
-    private const string BestTrainingMeanSquaredErrorQualityParameterName = "Best mean squared error (training)";
-
-    private const string TrainingAverageRelativeErrorQualityParameterName = "Average relative error (training)";
-    private const string MinTrainingAverageRelativeErrorQualityParameterName = "Min average relative error (training)";
-    private const string MaxTrainingAverageRelativeErrorQualityParameterName = "Max average relative error (training)";
-    private const string AverageTrainingAverageRelativeErrorQualityParameterName = "Average average relative error (training)";
-    private const string BestTrainingAverageRelativeErrorQualityParameterName = "Best average relative error (training)";
-
-    private const string TrainingRSquaredQualityParameterName = "R² (training)";
-    private const string MinTrainingRSquaredQualityParameterName = "Min R² (training)";
-    private const string MaxTrainingRSquaredQualityParameterName = "Max R² (training)";
-    private const string AverageTrainingRSquaredQualityParameterName = "Average R² (training)";
-    private const string BestTrainingRSquaredQualityParameterName = "Best R² (training)";
-
-    private const string TestMeanSquaredErrorQualityParameterName = "Mean squared error (test)";
-    private const string MinTestMeanSquaredErrorQualityParameterName = "Min mean squared error (test)";
-    private const string MaxTestMeanSquaredErrorQualityParameterName = "Max mean squared error (test)";
-    private const string AverageTestMeanSquaredErrorQualityParameterName = "Average mean squared error (test)";
-    private const string BestTestMeanSquaredErrorQualityParameterName = "Best mean squared error (test)";
-
-    private const string TestAverageRelativeErrorQualityParameterName = "Average relative error (test)";
-    private const string MinTestAverageRelativeErrorQualityParameterName = "Min average relative error (test)";
-    private const string MaxTestAverageRelativeErrorQualityParameterName = "Max average relative error (test)";
-    private const string AverageTestAverageRelativeErrorQualityParameterName = "Average average relative error (test)";
-    private const string BestTestAverageRelativeErrorQualityParameterName = "Best average relative error (test)";
-
-    private const string TestRSquaredQualityParameterName = "R² (test)";
-    private const string MinTestRSquaredQualityParameterName = "Min R² (test)";
-    private const string MaxTestRSquaredQualityParameterName = "Max R² (test)";
-    private const string AverageTestRSquaredQualityParameterName = "Average R² (test)";
-    private const string BestTestRSquaredQualityParameterName = "Best R² (test)";
-
-    private const string RSquaredValuesParameterName = "R²";
-    private const string MeanSquaredErrorValuesParameterName = "Mean squared error";
-    private const string RelativeErrorValuesParameterName = "Average relative error";
-    private const string BestSolutionResultName = "Best solution (on validiation set)";
-    private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+    private const string BestSolutionMeanSquaredErrorTrainingParameterName = "Best validation solution mean squared error (training)";
+    private const string BestSolutionMeanSquaredErrorTestParameterName = "Best validation solution mean squared error (test)";
+    private const string BestSolutionRSquaredTrainingParameterName = "Best validation solution R² (training)";
+    private const string BestSolutionRSquaredTestParameterName = "Best validation solution R² (test)";
+    private const string BestSolutionDirectionalSymmetryTrainingParameterName = "Best validation solution directional symmetry (training)";
+    private const string BestSolutionDirectionalSymmetryTestParameterName = "Best validation solution directional symmetry (test)";
+    private const string BestSolutionTheilsUTrainingParameterName = "Best validation solution Theil's U (training)";
+    private const string BestSolutionTheilsUTestParameterName = "Best validation solution Theil's U (test)";
+    private const string BestSolutionTheilsUTrendTrainingParameterName = "Best validation solution Theil's U with trend (training)";
+    private const string BestSolutionTheilsUTrendTestParameterName = "Best validation solution Theil's U with trend (test)";
 
     #region parameter properties
@@ -132,5 +104,5 @@
     }
     public ILookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator> EvaluatorParameter {
-      get { return (ILookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator>)Parameters["Evaluator"]; }
+      get { return (ILookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator>)Parameters[EvaluatorParameterName]; }
     }
     public IValueLookupParameter<IntValue> ValidationSamplesStartParameter {
@@ -146,6 +118,9 @@
       get { return (IValueLookupParameter<DoubleArray>)Parameters[LowerEstimationLimitParameterName]; }
     }
-    public IValueLookupParameter<IntValue> PredictionHorizonParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters[PredictionHorizonParameterName]; }
+    public IValueLookupParameter<IntValue> ValidationPredictionHorizonParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ValidationPredictionHorizonParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> ModelPredictionHorizonParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ModelPredictionHorizonParameterName]; }
     }
     public ILookupParameter<SymbolicTimeSeriesPrognosisSolution> BestSolutionParameter {
@@ -171,5 +146,35 @@
     }
     public ILookupParameter<BoolValue> MaximizationParameter {
-      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+      get { return (ILookupParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionMeanSquaredErrorTrainingParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionMeanSquaredErrorTrainingParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionMeanSquaredErrorTestParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionMeanSquaredErrorTestParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionRSquaredTrainingParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionRSquaredTrainingParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionRSquaredTestParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionRSquaredTestParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionDirectionalSymmetryTrainingParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionDirectionalSymmetryTrainingParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionDirectionalSymmetryTestParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionDirectionalSymmetryTestParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionTheilsUTrainingParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionTheilsUTrainingParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionTheilsUTestParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionTheilsUTestParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionTheilsUTrendTrainingParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionTheilsUTrendTrainingParameterName]; }
+    }
+    public ILookupParameter<DoubleArray> BestSolutionTheilsUTrendTestParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters[BestSolutionTheilsUTrendTestParameterName]; }
     }
     #endregion
@@ -199,6 +204,9 @@
       get { return LowerEstimationLimitParameter.ActualValue; }
     }
-    public IntValue PredictionHorizon {
-      get { return PredictionHorizonParameter.ActualValue; }
+    public IntValue ValidationPredictionHorizon {
+      get { return ValidationPredictionHorizonParameter.ActualValue; }
+    }
+    public IntValue ModelPredictionHorizon {
+      get { return ModelPredictionHorizonParameter.ActualValue; }
     }
     public StringValue ConditionVariableName {
@@ -219,4 +227,44 @@
     public BoolValue Maximization {
       get { return MaximizationParameter.ActualValue; }
+    }
+    public DoubleArray BestSolutionMeanSquaredErrorTraining {
+      get { return BestSolutionMeanSquaredErrorTrainingParameter.ActualValue; }
+      set { BestSolutionMeanSquaredErrorTrainingParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionMeanSquaredErrorTest {
+      get { return BestSolutionMeanSquaredErrorTestParameter.ActualValue; }
+      set { BestSolutionMeanSquaredErrorTestParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionRSquaredTraining {
+      get { return BestSolutionRSquaredTrainingParameter.ActualValue; }
+      set { BestSolutionRSquaredTrainingParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionRSquaredTest {
+      get { return BestSolutionRSquaredTestParameter.ActualValue; }
+      set { BestSolutionRSquaredTestParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionDirectionalSymmetryTraining {
+      get { return BestSolutionDirectionalSymmetryTrainingParameter.ActualValue; }
+      set { BestSolutionDirectionalSymmetryTrainingParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionDirectionalSymmetryTest {
+      get { return BestSolutionDirectionalSymmetryTestParameter.ActualValue; }
+      set { BestSolutionDirectionalSymmetryTestParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionTheilsUTraining {
+      get { return BestSolutionTheilsUTrainingParameter.ActualValue; }
+      set { BestSolutionTheilsUTrainingParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionTheilsUTest {
+      get { return BestSolutionTheilsUTestParameter.ActualValue; }
+      set { BestSolutionTheilsUTestParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionTheilsUTrendTraining {
+      get { return BestSolutionTheilsUTrendTrainingParameter.ActualValue; }
+      set { BestSolutionTheilsUTrendTrainingParameter.ActualValue = value; }
+    }
+    public DoubleArray BestSolutionTheilsUTrendTest {
+      get { return BestSolutionTheilsUTrendTestParameter.ActualValue; }
+      set { BestSolutionTheilsUTrendTestParameter.ActualValue = value; }
     }
     #endregion
@@ -236,6 +284,7 @@
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The first index of the validation partition of the data set."));
       Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The last index of the validation partition of the data set."));
-      Parameters.Add(new ValueLookupParameter<IntValue>(PredictionHorizonParameterName, "The number of time steps for which to create a forecast."));
-      Parameters.Add(new LookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator>("Evaluator", ""));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationPredictionHorizonParameterName, "The number of time steps for which to create a forecast for the validation procedure."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ModelPredictionHorizonParameterName, "Prediction horizont stored in the validation best model."));
+      Parameters.Add(new LookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator>(EvaluatorParameterName, ""));
       Parameters.Add(new ValueLookupParameter<DoubleArray>(UpperEstimationLimitParameterName, "The upper estimation limit that was set for the evaluation of the symbolic expression trees."));
       Parameters.Add(new ValueLookupParameter<DoubleArray>(LowerEstimationLimitParameterName, "The lower estimation limit that was set for the evaluation of the symbolic expression trees."));
@@ -247,5 +296,15 @@
       Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
       Parameters.Add(new ValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index.", new PercentValue(1)));
-      Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
+      Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionMeanSquaredErrorTrainingParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionMeanSquaredErrorTestParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionRSquaredTrainingParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionRSquaredTestParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionDirectionalSymmetryTrainingParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionDirectionalSymmetryTestParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionTheilsUTrainingParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionTheilsUTestParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionTheilsUTrendTrainingParameterName));
+      Parameters.Add(new LookupParameter<DoubleArray>(BestSolutionTheilsUTrendTestParameterName));
     }
 
@@ -255,7 +314,5 @@
     [StorableHook(Persistence.Default.CompositeSerializers.Storable.HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      //if (!Parameters.ContainsKey("Evaluator")) {
-      //  Parameters.Add(new LookupParameter<ISingleObjectiveSymbolicTimeSeriesPrognosisEvaluator>("Evaluator", ""));
-      //}
+
     }
 
@@ -287,5 +344,5 @@
         double validationQuality;
         validationQuality = evaluator.Evaluate(tree, ProblemData,
-          SymbolicExpressionTreeInterpreter, rows, PredictionHorizon.Value, LowerEstimationLimit, UpperEstimationLimit);
+          SymbolicExpressionTreeInterpreter, rows, ValidationPredictionHorizon.Value, LowerEstimationLimit, UpperEstimationLimit);
         if ((Maximization.Value && validationQuality > bestValidationQuality) ||
            (!Maximization.Value && validationQuality < bestValidationQuality)) {
@@ -304,5 +361,5 @@
         model.Description = "Best solution on validation partition found over the whole run.";
 
-        var solution = new SymbolicTimeSeriesPrognosisSolution((MultiVariateDataAnalysisProblemData)ProblemData.Clone(), model, PredictionHorizon.Value, conditionalVariableName, LowerEstimationLimit.ToArray(), UpperEstimationLimit.ToArray());
+        var solution = new SymbolicTimeSeriesPrognosisSolution((MultiVariateDataAnalysisProblemData)ProblemData.Clone(), model, ModelPredictionHorizon.Value, conditionalVariableName, LowerEstimationLimit.ToArray(), UpperEstimationLimit.ToArray());
         solution.Name = BestSolutionParameterName;
         solution.Description = "Best solution on validation partition found over the whole run.";
@@ -311,14 +368,118 @@
         BestSolutionQualityParameter.ActualValue = new DoubleValue(bestValidationQuality);
 
-        // BestSymbolicTimeSeriesPrognosisSolutionAnalyzer.UpdateBestSolutionResults(solution, ProblemData, Results, Generations, VariableFrequencies);
+        #region calculate accuracy
+        List<string> targetVariables = ProblemData.TargetVariables.CheckedItems.Select(x => x.Value.Value).ToList();
+
+        // create a list of time series evaluators for each target variable
+        Dictionary<string, List<IOnlineEvaluator>> trainingEvaluators =
+          new Dictionary<string, List<IOnlineEvaluator>>();
+        Dictionary<string, List<IOnlineEvaluator>> testEvaluators =
+          new Dictionary<string, List<IOnlineEvaluator>>();
+        foreach (string targetVariable in targetVariables) {
+          trainingEvaluators.Add(targetVariable, new List<IOnlineEvaluator>());
+          trainingEvaluators[targetVariable].Add(new OnlineMeanSquaredErrorEvaluator());
+          trainingEvaluators[targetVariable].Add(new OnlinePearsonsRSquaredEvaluator());
+          trainingEvaluators[targetVariable].Add(new OnlineDirectionalSymmetryEvaluator());
+          trainingEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator());
+          trainingEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator(10));
+
+          testEvaluators.Add(targetVariable, new List<IOnlineEvaluator>());
+          testEvaluators[targetVariable].Add(new OnlineMeanSquaredErrorEvaluator());
+          testEvaluators[targetVariable].Add(new OnlinePearsonsRSquaredEvaluator());
+          testEvaluators[targetVariable].Add(new OnlineDirectionalSymmetryEvaluator());
+          testEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator());
+          testEvaluators[targetVariable].Add(new OnlineTheilsUStatisticEvaluator(10));
+        }
+
+        Evaluate(solution, solution.ProblemData.Dataset, targetVariables, conditionalVariableName, trainingStart, trainingEnd, trainingEvaluators);
+        Evaluate(solution, solution.ProblemData.Dataset, targetVariables, conditionalVariableName, testStart, testEnd, testEvaluators);
+        #endregion
+        BestSolutionMeanSquaredErrorTraining = new DoubleArray((from variable in targetVariables
+                                                                let eval = trainingEvaluators[variable].OfType<OnlineMeanSquaredErrorEvaluator>().Single()
+                                                                select TryGetValue(eval))
+                                                                .ToArray());
+        BestSolutionMeanSquaredErrorTest = new DoubleArray((from variable in targetVariables
+                                                            select TryGetValue(testEvaluators[variable].OfType<OnlineMeanSquaredErrorEvaluator>().Single()))
+                                                          .ToArray());
+        BestSolutionRSquaredTraining = new DoubleArray((from variable in targetVariables
+                                                        select TryGetValue(trainingEvaluators[variable].OfType<OnlinePearsonsRSquaredEvaluator>().Single()))
+                                                                .ToArray());
+        BestSolutionRSquaredTest = new DoubleArray((from variable in targetVariables
+                                                    select TryGetValue(testEvaluators[variable].OfType<OnlinePearsonsRSquaredEvaluator>().Single()))
+                                                          .ToArray());
+        BestSolutionDirectionalSymmetryTraining = new DoubleArray((from variable in targetVariables
+                                                                   select TryGetValue(trainingEvaluators[variable].OfType<OnlineDirectionalSymmetryEvaluator>().Single()))
+                                                                .ToArray());
+        BestSolutionDirectionalSymmetryTest = new DoubleArray((from variable in targetVariables
+                                                               select TryGetValue(testEvaluators[variable].OfType<OnlineDirectionalSymmetryEvaluator>().Single()))
+                                                          .ToArray());
+        BestSolutionTheilsUTraining = new DoubleArray((from variable in targetVariables
+                                                       select TryGetValue(trainingEvaluators[variable].OfType<OnlineTheilsUStatisticEvaluator>().First()))
+                                                                .ToArray());
+        BestSolutionTheilsUTest = new DoubleArray((from variable in targetVariables
+                                                   select TryGetValue(testEvaluators[variable].OfType<OnlineTheilsUStatisticEvaluator>().First()))
+                                                          .ToArray());
+        BestSolutionTheilsUTrendTraining = new DoubleArray((from variable in targetVariables
+                                                            select TryGetValue(trainingEvaluators[variable].OfType<OnlineTheilsUStatisticEvaluator>().Skip(1).First()))
+                                                                .ToArray());
+        BestSolutionTheilsUTrendTest = new DoubleArray((from variable in targetVariables
+                                                        select TryGetValue(testEvaluators[variable].OfType<OnlineTheilsUStatisticEvaluator>().Skip(1).First()))
+                                                          .ToArray());
+        if (!Results.ContainsKey(BestSolutionParameterName)) {
+          for (int i = 0; i < targetVariables.Count; i++) {
+            Results.Add(new Result(BestSolutionMeanSquaredErrorTrainingParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionMeanSquaredErrorTraining[i])));
+            Results.Add(new Result(BestSolutionMeanSquaredErrorTestParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionMeanSquaredErrorTest[i])));
+            Results.Add(new Result(BestSolutionRSquaredTrainingParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionRSquaredTraining[i])));
+            Results.Add(new Result(BestSolutionRSquaredTestParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionRSquaredTest[i])));
+            Results.Add(new Result(BestSolutionDirectionalSymmetryTrainingParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionDirectionalSymmetryTraining[i])));
+            Results.Add(new Result(BestSolutionDirectionalSymmetryTestParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionDirectionalSymmetryTest[i])));
+            Results.Add(new Result(BestSolutionTheilsUTrainingParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionTheilsUTraining[i])));
+            Results.Add(new Result(BestSolutionTheilsUTestParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionTheilsUTest[i])));
+            Results.Add(new Result(BestSolutionTheilsUTrendTrainingParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionTheilsUTrendTraining[i])));
+            Results.Add(new Result(BestSolutionTheilsUTrendTestParameterName + " (" + targetVariables[i] + ")",
+              new DoubleValue(BestSolutionTheilsUTrendTest[i])));
+          }
+        } else {
+          for (int i = 0; i < targetVariables.Count; i++) {
+            Results[BestSolutionMeanSquaredErrorTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionMeanSquaredErrorTraining[i]);
+            Results[BestSolutionMeanSquaredErrorTestParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionMeanSquaredErrorTest[i]);
+            Results[BestSolutionRSquaredTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionRSquaredTraining[i]);
+            Results[BestSolutionRSquaredTestParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionRSquaredTest[i]);
+            Results[BestSolutionDirectionalSymmetryTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionDirectionalSymmetryTraining[i]);
+            Results[BestSolutionDirectionalSymmetryTestParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionDirectionalSymmetryTest[i]);
+            Results[BestSolutionTheilsUTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionTheilsUTraining[i]);
+            Results[BestSolutionTheilsUTestParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionTheilsUTest[i]);
+            Results[BestSolutionTheilsUTrendTrainingParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionTheilsUTrendTraining[i]);
+            Results[BestSolutionTheilsUTrendTestParameterName + " (" + targetVariables[i] + ")"].Value =
+              new DoubleValue(BestSolutionTheilsUTrendTest[i]);
+          }
+        }
       }
 
       if (!Results.ContainsKey(BestSolutionQualityValuesParameterName)) {
-        Results.Add(new Result(BestSolutionResultName, BestSolutionParameter.ActualValue));
+        Results.Add(new Result(BestSolutionParameterName, BestSolutionParameter.ActualValue));
         Results.Add(new Result(BestSolutionQualityValuesParameterName, new DataTable(BestSolutionQualityValuesParameterName, BestSolutionQualityValuesParameterName)));
         Results.Add(new Result(BestSolutionQualityParameterName, new DoubleValue()));
         Results.Add(new Result(CurrentBestValidationQualityParameterName, new DoubleValue()));
       }
-      Results[BestSolutionResultName].Value = BestSolutionParameter.ActualValue;
+      Results[BestSolutionParameterName].Value = BestSolutionParameter.ActualValue;
       Results[BestSolutionQualityParameterName].Value = new DoubleValue(BestSolutionQualityParameter.ActualValue.Value);
       Results[CurrentBestValidationQualityParameterName].Value = new DoubleValue(bestValidationQuality);
@@ -329,4 +490,13 @@
       #endregion
       return base.Apply();
+    }
+
+    private double TryGetValue(IOnlineEvaluator eval) {
+      try {
+        return eval.Value;
+      }
+      catch {
+        return double.NaN;
+      }
     }
 
@@ -364,5 +534,43 @@
     }
 
-
+    private void Evaluate(SymbolicTimeSeriesPrognosisSolution solution, Dataset dataset, IEnumerable<string> targetVariables, string conditionalEvaluationVariable, int start, int end, Dictionary<string, List<IOnlineEvaluator>> evaluators) {
+
+      for (int row = start; row < end; row++) {
+        if (string.IsNullOrEmpty(conditionalEvaluationVariable) || dataset[conditionalEvaluationVariable, row] != 0) {
+          // prepare evaluators for each target variable for a new prediction window
+          foreach (var entry in evaluators) {
+            double referenceOriginalValue = dataset[entry.Key, row - 1];
+            foreach (IOnlineTimeSeriesPrognosisEvaluator evaluator in entry.Value.OfType<IOnlineTimeSeriesPrognosisEvaluator>()) {
+              evaluator.StartNewPredictionWindow(referenceOriginalValue);
+            }
+          }
+
+
+          if (string.IsNullOrEmpty(conditionalEvaluationVariable) ||
+            dataset[conditionalEvaluationVariable, row] > 0) {
+            int timestep = 0;
+            foreach (double[] x in solution.GetPrognosis(row)) {
+              int targetIndex = 0;
+              if (row + timestep < dataset.Rows) {
+                foreach (var targetVariable in targetVariables) {
+                  double originalValue = dataset[targetVariable, row + timestep];
+                  double estimatedValue = x[targetIndex];
+                  if (IsValidValue(originalValue) && IsValidValue(estimatedValue)) {
+                    foreach (IOnlineEvaluator evaluator in evaluators[targetVariable]) {
+                      evaluator.Add(originalValue, estimatedValue);
+                    }
+                  }
+                  targetIndex++;
+                }
+              }
+              timestep++;
+            }
+          }
+        }
+      }
+    }
+    private bool IsValidValue(double d) {
+      return !(double.IsNaN(d) || double.IsInfinity(d));
+    }
 
     private static void AddValue(DataTable table, double data, string name, string description) {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Evaluators/SymbolicTimeSeriesPrognosisNormalizedMseEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Evaluators/SymbolicTimeSeriesPrognosisNormalizedMseEvaluator.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/Evaluators/SymbolicTimeSeriesPrognosisNormalizedMseEvaluator.cs	(revision 5305)
@@ -43,6 +43,15 @@
   public class SymbolicTimeSeriesPrognosisNormalizedMseEvaluator : SymbolicTimeSeriesPrognosisEvaluator {
 
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisNormalizedMseEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisNormalizedMseEvaluator(SymbolicTimeSeriesPrognosisNormalizedMseEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public SymbolicTimeSeriesPrognosisNormalizedMseEvaluator()
       : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisNormalizedMseEvaluator(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SingleObjectiveSymbolicTimeSeriesPrognosisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SingleObjectiveSymbolicTimeSeriesPrognosisProblem.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SingleObjectiveSymbolicTimeSeriesPrognosisProblem.cs	(revision 5305)
@@ -163,5 +163,5 @@
           bestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
           bestValidationSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
-          bestValidationSolutionAnalyzer.PredictionHorizonParameter.ActualName = PredictionHorizonParameter.Name;
+          bestValidationSolutionAnalyzer.ValidationPredictionHorizonParameter.ActualName = PredictionHorizonParameter.Name;
           bestValidationSolutionAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
           bestValidationSolutionAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SymbolicTimeSeriesPrognosisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SymbolicTimeSeriesPrognosisProblem.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate.TimeSeriesPrognosis/3.3/Symbolic/SymbolicTimeSeriesPrognosisProblem.cs	(revision 5305)
@@ -155,8 +155,7 @@
 
     [Storable]
-    private SymbolicTimeSeriesPrognosisGrammar grammar;
+    private List<IOperator> operators;
     [Storable]
-    private List<IOperator> operators;
-
+    private SymbolicTimeSeriesPrognosisGrammar timeSeriesPrognosisGrammar;
     [StorableConstructor]
     protected SymbolicTimeSeriesPrognosisProblem(bool deserializing) : base(deserializing) { }
@@ -164,5 +163,5 @@
       : base(original, cloner) {
       operators = original.operators.Select(x => (IOperator)cloner.Clone(x)).ToList();
-      grammar = (SymbolicTimeSeriesPrognosisGrammar)cloner.Clone(original.grammar);
+      timeSeriesPrognosisGrammar = cloner.Clone(original.timeSeriesPrognosisGrammar);
       RegisterParameterEvents();
       RegisterParameterValueEvents();
@@ -171,6 +170,6 @@
       : base() {
       SymbolicExpressionTreeCreator creator = new ProbabilisticTreeCreator();
-      grammar = new SymbolicTimeSeriesPrognosisGrammar(1);
-      var globalGrammar = new GlobalSymbolicExpressionGrammar(grammar);
+      timeSeriesPrognosisGrammar = new SymbolicTimeSeriesPrognosisGrammar(1);
+      var globalGrammar = new GlobalSymbolicExpressionGrammar(timeSeriesPrognosisGrammar);
       var interpreter = new SymbolicTimeSeriesExpressionInterpreter();
       Parameters.Add(new ValueParameter<SymbolicExpressionTreeCreator>("SolutionCreator", "The operator which should be used to create new symbolic time series prognosis solutions.", creator));
@@ -179,6 +178,6 @@
       Parameters.Add(new ValueParameter<IntValue>("MaxExpressionLength", "Maximal length of the symbolic expression.", new IntValue(100)));
       Parameters.Add(new ValueParameter<IntValue>("MaxExpressionDepth", "Maximal depth of the symbolic expression.", new IntValue(10)));
-      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefiningBranches", "Maximal number of automatically defined functions.", (IntValue)new IntValue(0).AsReadOnly()));
-      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions.", (IntValue)new IntValue(0).AsReadOnly()));
+      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefiningBranches", "Maximal number of automatically defined functions.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0)));
       Parameters.Add(new ValueParameter<IntValue>("PredictionHorizon", "The number of time steps for which to create a forecast.", new IntValue(1)));
       Parameters.Add(new ValueParameter<DoubleArray>("UpperEstimationLimit", "The upper limit for the estimated values for each component."));
@@ -230,5 +229,5 @@
       UpdateGrammar();
     }
-    protected virtual void OnGrammarChanged(EventArgs e) { }
+    protected virtual void OnGrammarChanged(EventArgs e) { UpdateGrammar(); }
     protected virtual void OnOperatorsChanged(EventArgs e) { RaiseOperatorsChanged(e); }
     protected virtual void OnSolutionCreatorChanged(EventArgs e) {
@@ -245,4 +244,9 @@
 
     #region event handlers
+    private void FunctionTreeGrammarParameter_ValueChanged(object sender, EventArgs e) {
+      if (!(FunctionTreeGrammar is GlobalSymbolicExpressionGrammar))
+        FunctionTreeGrammar = new GlobalSymbolicExpressionGrammar(FunctionTreeGrammar);
+      OnGrammarChanged(e);
+    }
     private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
       OnSolutionCreatorChanged(e);
@@ -268,14 +272,15 @@
     private void UpdateGrammar() {
       var selectedTargetVariables = MultiVariateDataAnalysisProblemData.TargetVariables.CheckedItems;
-      grammar.SetResultProducingBranches(selectedTargetVariables.Count());
-
-      foreach (var varSymbol in grammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable>()) {
+      timeSeriesPrognosisGrammar.SetResultProducingBranches(selectedTargetVariables.Count());
+
+      foreach (var varSymbol in FunctionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable>()) {
         varSymbol.VariableNames = MultiVariateDataAnalysisProblemData.InputVariables.CheckedItems.Select(x => x.Value.Value);
       }
 
-      var globalGrammar = new GlobalSymbolicExpressionGrammar(grammar);
-      globalGrammar.MaxFunctionArguments = MaxFunctionArguments.Value;
-      globalGrammar.MaxFunctionDefinitions = MaxFunctionDefiningBranches.Value;
-      FunctionTreeGrammar = globalGrammar;
+      var globalGrammar = FunctionTreeGrammar as GlobalSymbolicExpressionGrammar;
+      if (globalGrammar != null) {
+        globalGrammar.MaxFunctionArguments = MaxFunctionArguments.Value;
+        globalGrammar.MaxFunctionDefinitions = MaxFunctionDefiningBranches.Value;
+      }
     }
     private void UpdateEstimationLimits() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate/3.3/MultiVariateDataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate/3.3/MultiVariateDataAnalysisProblem.cs	(revision 5304)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate/3.3/MultiVariateDataAnalysisProblem.cs	(revision 5305)
@@ -76,5 +76,4 @@
       RaiseReset(e);
     }
-
     private void RegisterParameterEvents() {
       MultiVariateDataAnalysisProblemDataParameter.ValueChanged += new EventHandler(MultiVariateDataAnalysisProblemDataParameter_ValueChanged);
Index: branches/DataAnalysis/Main/Main.csproj
===================================================================
--- branches/DataAnalysis/Main/Main.csproj	(revision 5304)
+++ branches/DataAnalysis/Main/Main.csproj	(revision 5305)
@@ -80,5 +80,5 @@
 
 call CopyAssemblies.cmd
-UpdateLocalInstallation.cmd</PostBuildEvent>
+call UpdateLocalInstallation.cmd</PostBuildEvent>
   </PropertyGroup>
   <ItemGroup>
