'In-sample prediction and out-of-sample forecasting
Parameters
start : int, str, or datetime, optional
Zero-indexed observation number at which to start forecasting, ie.,
the first forecast is start. Can also be a date string to
parse or a datetime type. Default is the the zeroth observation.
end : int, str, or datetime, optional
Zero-indexed observation number at which to end forecasting, ie.,
the first forecast is start. Can also be a date string to
parse or a datetime type. However, if the dates index does not
have a fixed frequency, end must be an integer index if you
want out of sample prediction. Default is the last observation in
the sample.
exog : array_like, optional
If the model includes exogenous regressors, you must provide
exactly enough out-of-sample values for the exogenous variables if
end is beyond the last observation in the sample.
dynamic : boolean, int, str, or datetime, optional
Integer offset relative to `start` at which to begin dynamic
prediction. Can also be an absolute date string to parse or a
datetime type (these are not interpreted as offsets).
Prior to this observation, true endogenous values will be used for
prediction; starting with this observation and continuing through
the end of prediction, forecasted endogenous values will be used
instead.
**kwargs
Additional arguments may required for forecasting beyond the end
of the sample. See `FilterResults.predict` for more details.
Returns
forecast : array
Array of out of sample forecasts.'

def get_prediction(self, start=None, end=None, dynamic=False, index=None, exog=None, **kwargs):

    if (start is None):
        start = self.model._index[0]
    (_start, _end, _out_of_sample, prediction_index) = self.model._get_prediction_index(start, end, index, silent=True)
    if (_out_of_sample and (self.model.k_exog > 0)):
        nobs = (self.model.data.orig_endog.shape[0] + _out_of_sample)
        endog = np.zeros((nobs, self.model.k_endog))
        if (self.model.k_exog > 0):
            if (exog is None):
                raise ValueError('Out-of-sample    forecasting    in    a    model    with    a    regression    component    requires    additional    exogenous    values    via    the    `exog`    argument.')
            exog = np.array(exog)
            required_exog_shape = (_out_of_sample, self.model.k_exog)
            if (not (exog.shape == required_exog_shape)):
                raise ValueError(('Provided    exogenous    values    are    not    of    the    appropriate    shape.    Required    %s,    got    %s.' % (str(required_exog_shape), str(exog.shape))))
            exog = np.c_[(self.model.data.orig_exog.T, exog.T)].T
        model = DynamicFactor(endog, k_factors=self.model.k_factors, factor_order=self.model.factor_order, exog=exog, error_order=self.model.error_order, error_var=self.model.error_var, error_cov_type=self.model.error_cov_type, enforce_stationarity=self.model.enforce_stationarity)
        model.update(self.params)
        for name in self.filter_results.shapes.keys():
            if (name == 'obs'):
                continue
            mat = getattr(model.ssm, name)
            if (mat.shape[(-1)] > 1):
                if (len(mat.shape) == 2):
                    kwargs[name] = mat[:, (- _out_of_sample):]
                else:
                    kwargs[name] = mat[:, :, (- _out_of_sample):]
    elif ((self.model.k_exog == 0) and (exog is not None)):
        warn('Exogenous    array    provided    to    predict,    but    additional    data    not    required.    `exog`    argument    ignored.', ValueWarning)
    return super(DynamicFactorResults, self).get_prediction(start=start, end=end, dynamic=dynamic, index=index, exog=exog, **kwargs)
