Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 7154)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 7160)
@@ -49,5 +49,5 @@
     public override IEnumerable<IEnumerable<double>> PrognosedTrainingValues {
       get {
-        return GetPrognosedValues(Enumerable.Range(ProblemData.TrainingPartition.Start, 1),
+        return GetPrognosedValues(ProblemData.TrainingIndizes.Take(1),
           ProblemData.TrainingPartition.End - ProblemData.TrainingPartition.Start)
           .First();
@@ -56,5 +56,5 @@
     public override IEnumerable<IEnumerable<double>> PrognosedTestValues {
       get {
-        return GetPrognosedValues(Enumerable.Range(ProblemData.TestPartition.Start, 1),
+        return GetPrognosedValues(ProblemData.TestIndizes.Take(1),
           ProblemData.TestPartition.End - ProblemData.TestPartition.Start)
           .First();
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7154)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7160)
@@ -45,6 +45,10 @@
     private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
     private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
-    private const string TrainingTheilsUStatisticResultName = "Average Theil's U (training)";
-    private const string TestTheilsUStatisticResultName = "Average Theil's U (test)";
+    private const string TrainingTheilsUStatisticLastResultName = "Average Theil's U (last) (training)";
+    private const string TestTheilsUStatisticLastResultName = "Average Theil's U (last) (test)";
+    private const string TrainingTheilsUStatisticMeanResultName = "Average Theil's U (mean) (training)";
+    private const string TestTheilsUStatisticMeanResultName = "Average Theil's U (mean) (test)";
+    private const string TrainingTheilsUStatisticMAResultName = "Average Theil's U (moving average) (training)";
+    private const string TestTheilsUStatisticMAResultName = "Average Theil's U (moving average) (test)";
 
     public new ITimeSeriesPrognosisModel Model {
@@ -56,4 +60,16 @@
       get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
       set { base.ProblemData = value; }
+    }
+
+    [Storable]
+    private int horizon;
+    public int Horizon {
+      get { return horizon; }
+      set {
+        if (horizon != value) {
+          horizon = value;
+          RecalculateResults();
+        }
+      }
     }
 
@@ -119,11 +135,27 @@
       private set { this[TestWeightedDirectionalSymmetryResultName].Value = new DoubleArray(value); }
     }
-    public double[] TrainingTheilsUStatistic {
-      get { return ((DoubleArray)this[TrainingTheilsUStatisticResultName].Value).ToArray(); }
-      private set { this[TrainingTheilsUStatisticResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestTheilsUStatistic {
-      get { return ((DoubleArray)this[TestTheilsUStatisticResultName].Value).ToArray(); }
-      private set { this[TestTheilsUStatisticResultName].Value = new DoubleArray(value); }
+    public double[] TrainingTheilsUStatisticLast {
+      get { return ((DoubleArray)this[TrainingTheilsUStatisticLastResultName].Value).ToArray(); }
+      private set { this[TrainingTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
+    }
+    public double[] TestTheilsUStatisticLast {
+      get { return ((DoubleArray)this[TestTheilsUStatisticLastResultName].Value).ToArray(); }
+      private set { this[TestTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
+    }
+    public double[] TrainingTheilsUStatisticMean {
+      get { return ((DoubleArray)this[TrainingTheilsUStatisticMeanResultName].Value).ToArray(); }
+      private set { this[TrainingTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
+    }
+    public double[] TestTheilsUStatisticMean {
+      get { return ((DoubleArray)this[TestTheilsUStatisticMeanResultName].Value).ToArray(); }
+      private set { this[TestTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
+    }
+    public double[] TrainingTheilsUStatisticMovingAverage {
+      get { return ((DoubleArray)this[TrainingTheilsUStatisticMAResultName].Value).ToArray(); }
+      private set { this[TrainingTheilsUStatisticMAResultName].Value = new DoubleArray(value); }
+    }
+    public double[] TestTheilsUStatisticMovingAverage {
+      get { return ((DoubleArray)this[TestTheilsUStatisticMAResultName].Value).ToArray(); }
+      private set { this[TestTheilsUStatisticMAResultName].Value = new DoubleArray(value); }
     }
     #endregion
@@ -133,4 +165,5 @@
     protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner)
       : base(original, cloner) {
+      this.horizon = original.horizon;
     }
     protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
@@ -150,11 +183,16 @@
       Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleArray()));
       Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the test partition", new DoubleArray()));
+      Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleArray()));
+      Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleArray()));
+      Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleArray()));
+      Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleArray()));
+      Add(new Result(TrainingTheilsUStatisticMAResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleArray()));
+      Add(new Result(TestTheilsUStatisticMAResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleArray()));
+      horizon = 1;
     }
 
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-
+      if (horizon == 0) horizon = 1;
     }
 
@@ -207,6 +245,10 @@
       var trainingWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
       var testWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
-      var trainingTheilsUCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var testTheilsUCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var trainingTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var testTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var trainingTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var testTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var trainingTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var testTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
       for (int i = 0; i < targetVariables.Length; i++) {
         trainingDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
@@ -214,25 +256,63 @@
         trainingWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
         testWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
-        trainingTheilsUCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        testTheilsUCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        trainingTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        testTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        trainingTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        testTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        trainingTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        testTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
       }
 
-      var allPrognosedTrainingValues = PrognosedTrainingValues.SelectMany(x => x).ToArray();
-      var allPrognosedTestValues = PrognosedTestValues.SelectMany(x => x).ToArray();
-      for (int t = 0; t < targetVariables.Length; t++) {
-        var actualTrainingValues = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes);
-        double startTrainingValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], ProblemData.TrainingIndizes.First() - 1);
-        var prognosedTrainingValues = allPrognosedTrainingValues.Skip(t).TakeEvery(targetVariables.Length);
-        trainingDsCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
-        trainingWdsCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
-        trainingTheilsUCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
-
-        var actualTestValues = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TestIndizes);
-        double startTestValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], ProblemData.TestIndizes.First() - 1);
-        var prognosedTestValues = allPrognosedTestValues.Skip(t).TakeEvery(targetVariables.Length);
-        testDsCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
-        testWdsCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
-        testTheilsUCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
+      var allPrognosedTrainingValues = GetPrognosedValues(ProblemData.TrainingIndizes, horizon).GetEnumerator();
+      foreach (var row in ProblemData.TrainingIndizes) {
+        if (row + horizon < ProblemData.Dataset.Rows) {
+          allPrognosedTrainingValues.MoveNext();
+          var prognosedTrainingValues = allPrognosedTrainingValues.Current.SelectMany(x => x).ToArray();
+          for (int t = 0; t < targetVariables.Length; t++) {
+            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
+                                                                         Enumerable.Range(row, horizon));
+            int maWindow = 10 * horizon;
+            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
+                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
+                                                    where r > 0
+                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
+                                                   ).Average();
+            var mean = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes).Median();
+            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
+            var prognosedContinuation = prognosedTrainingValues.Skip(t).TakeEvery(targetVariables.Length);
+            trainingDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            trainingWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            trainingTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            trainingTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
+            trainingTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
+          }
+        }
       }
+      var allPrognosedTestValues = GetPrognosedValues(ProblemData.TestIndizes, horizon).GetEnumerator();
+      foreach (var row in ProblemData.TestIndizes) {
+        if (row + horizon < ProblemData.Dataset.Rows) {
+          allPrognosedTestValues.MoveNext();
+          var prognosedTestValues = allPrognosedTestValues.Current.SelectMany(x => x).ToArray();
+          for (int t = 0; t < targetVariables.Length; t++) {
+            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
+                                                                         Enumerable.Range(row, horizon));
+            int maWindow = 10 * horizon;
+            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
+                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
+                                                    where r > 0
+                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
+                                                   ).Average();
+            // mean must be calculated on the training set!
+            var mean = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes).Median();
+            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
+            var prognosedContinuation = prognosedTestValues.Skip(t).TakeEvery(targetVariables.Length);
+            testDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            testWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            testTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
+            testTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
+            testTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
+          }
+        }
+      }
 
       TrainingDirectionalSymmetry = trainingDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
@@ -244,8 +324,20 @@
       TestWeightedDirectionalSymmetry = testWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
         .ToArray();
-      TrainingTheilsUStatistic = trainingDsCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestTheilsUStatistic = testTheilsUCalculators
+      TrainingTheilsUStatisticLast = trainingTheilsULastCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TestTheilsUStatisticLast = testTheilsULastCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TrainingTheilsUStatisticMean = trainingTheilsUMeanCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TestTheilsUStatisticMean = testTheilsUMeanCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TrainingTheilsUStatisticMovingAverage = trainingTheilsUMovingAverageCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TestTheilsUStatisticMovingAverage = testTheilsUMovingAverageCalculators
         .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
         .ToArray();
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 7154)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 7160)
@@ -23,4 +23,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface ITimeSeriesPrognosisSolution : IDataAnalysisSolution {
+    int Horizon { get; set; }
     new ITimeSeriesPrognosisModel Model { get; }
     new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
@@ -40,6 +41,8 @@
     double[] TrainingNormalizedMeanSquaredError { get; }
     double[] TestNormalizedMeanSquaredError { get; }
-    double[] TrainingTheilsUStatistic { get; }
-    double[] TestTheilsUStatistic { get; }
+    double[] TrainingTheilsUStatisticLast { get; }
+    double[] TestTheilsUStatisticLast { get; }
+    double[] TrainingTheilsUStatisticMean { get; }
+    double[] TestTheilsUStatisticMean { get; }
     double[] TrainingDirectionalSymmetry { get; }
     double[] TestDirectionalSymmetry { get; }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 7154)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 7160)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 
@@ -52,4 +53,8 @@
 
     public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      Add(startValue, actualContinuation.Select(x => startValue), actualContinuation, predictedContinuation);
+    }
+
+    public void Add(double startValue, IEnumerable<double> referenceContinuation, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
       if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
@@ -57,8 +62,11 @@
         var actualEnumerator = actualContinuation.GetEnumerator();
         var predictedEnumerator = predictedContinuation.GetEnumerator();
-        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
+        var referenceEnumerator = referenceContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & referenceEnumerator.MoveNext()
+          & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
           double actual = actualEnumerator.Current;
           double predicted = predictedEnumerator.Current;
-          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+          double reference = referenceEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted) || double.IsNaN(reference)) {
             errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
           } else {
@@ -67,10 +75,10 @@
             squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
 
-            double errorNoChange = (actual - startValue);
-            unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
+            double errorReference = (reference - startValue) - (actual - startValue);
+            unbiasedEstimatorMeanCalculator.Add(errorReference * errorReference);
           }
         }
         // check if both enumerators are at the end to make sure both enumerations have the same length
-        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext() || referenceEnumerator.MoveNext()) {
           errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
         } else {
@@ -79,4 +87,5 @@
       }
     }
+
 
     public void Reset() {
