code: def optimize(self, timeSeries, forecastingMethods=None, startingPercentage=0.0, endPercentage=100.0):
          
          # no forecasting methods provided
          if forecastingMethods is None or len(forecastingMethods) == 0:
              raise ValueError("forecastingMethods cannot be empty.")
docs: Runs the optimization on the given TimeSeries.
  
          :param TimeSeries timeSeries:    TimeSeries instance that requires an optimized forecast.
          :param list forecastingMethods:    List of forecastingMethods that will be used for optimization.
          :param float startingPercentage: Defines the start of the interval. This has to be a value in [0.0, 100.0].
              It represents the value, where the error calculation should be started.
              25.0 for example means that the first 25% of all calculated errors will be ignored.
          :param float endPercentage:    Defines the end of the interval. This has to be a value in [0.0, 100.0].
              It represents the value, after which all error values will be ignored. 90.0 for example means that
              the last 10% of all local errors will be ignored.
  
  
          :return:    Returns the optimized forecasting method with the smallest error.
          :rtype:     (BaseForecastingMethod, Dictionary)
  
          :raise:    Raises a :py:exc:`ValueError` ValueError if no forecastingMethods is empty.