Data Loading

Contents

Data Loading#

class forecast_evaluation.data.DensityForecastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, extra_ids: list[str] | None = None, compute_levels: bool = True)[source]#

Bases: ForecastData

Class for density forecasts with quantile information.

Extends the ForecastData class to handle density forecasts. DensityForecastData objects include a density_forecasts attribute that contains forecasts with quantile information (basically an extra column indicating quantiles). It can still handle point forecasts with the forecasts attribute.

Parameters:
  • outturns_data (pd.DataFrame, optional) – DataFrame containing outturn (actual) data.

  • forecasts_data (pd.DataFrame, optional) – DataFrame containing point forecast records.

  • density_forecasts_data (pd.DataFrame, optional) – DataFrame containing density forecast records. Must include ‘quantile’ column.

  • point_estimator (str, optional) – Estimator for point forecasts; can be ‘median’, ‘mean’ or ‘mode’. Default is ‘median’.

  • load_fer (bool, optional) – Whether to load FER (Forecast Evaluation Report) data. Default is False.

  • extra_ids (list of str, optional) – Additional identification columns beyond ‘source’ and ‘quantile’.

Examples

>>> import pandas as pd
>>> from forecast_evaluation.data import DensityForecastData
>>>
>>> # Create sample density forecasts
>>> df = pd.DataFrame({
...     'date': pd.date_range('2023-01-01', periods=4, freq='QE'),
...     'vintage_date': pd.Timestamp('2023-01-01'),
...     'variable': 'gdp',
...     'frequency': 'Q',
...     'forecast_horizon': [1, 2, 3, 4],
...     'source': 'model_1',
...     'quantile': 0.5,
...     'value': [100, 101, 102, 103]
... })
>>>
>>> density_data = DensityForecastData(forecasts_data=df)
>>> median = density_data.get_median_forecast()
__init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, extra_ids: list[str] | None = None, compute_levels: bool = True)[source]#

Initialise DensityForecastData.

Initialises the density forecast data object. If forecasts_data is provided, it will be validated and added. The ‘quantile’ column is automatically included as an identification column.

add_density_forecasts(df: DataFrame, extra_ids: list[str] | None = None) → None[source]#

Validate and add density forecasts with quantile column.

Parameters:
  • df (pd.DataFrame) – DataFrame containing density forecast records. Must include ‘quantile’ column with values between 0 and 1.

  • extra_ids (list of str, optional) – Additional identification columns beyond ‘source’ and ‘quantile’.

Raises:

ValueError – If ‘quantile’ column is missing from the DataFrame.

Examples

>>> density_data = DensityForecastData()
>>> df = pd.DataFrame({
...     'date': ['2023-01-01'],
...     'vintage_date': ['2023-01-01'],
...     'variable': ['gdp'],
...     'frequency': ['Q'],
...     'forecast_horizon': [1],
...     'source': ['model_1'],
...     'quantile': [0.5],
...     'value': [100]
... })
>>> density_data.add_density_forecasts(df)
clear_filter() → None[source]#

Reset both parent forecasts and density forecasts to include all original data.

property density_forecasts: DataFrame#

Get density forecasts with quantile information.

filter(start_date: str | None = None, end_date: str | None = None, start_vintage: str | None = None, end_vintage: str | None = None, variables: list[str] | None = None, metrics: list[str] | None = None, sources: list[str] | None = None, frequencies: list[str] | None = None, custom_filter: Callable[[DataFrame], DataFrame] | None = None, filter_point_forecasts: bool | None = True, filter_density_forecasts: bool | None = True)[source]#

Filter the forecasts and main tables to only include data within specified date and vintage ranges, and optionally by variables, metrics, sources, or a custom filter.

Parameters:
  • start_date (str, optional) – Start date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest date.

  • end_date (str, optional) – End date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest date.

  • start_vintage (str, optional) – Start vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest vintage.

  • end_vintage (str, optional) – End vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest vintage.

  • variables (Optional[Union[str, list[str]]] = None) – List of variable identifiers to filter. Default is None (no filtering).

  • metrics (Optional[list[str]] = None) – List of metric identifiers to filter. Default is None (no filtering).

  • sources (Optional[Union[str, list[str]]] = None) – List of source identifiers to filter. Default is None (no filtering).

  • frequencies (Optional[Union[str, list[str]]] = None) – List of frequency identifiers to filter. Default is None (no filtering).

  • custom_filter (Callable[[pd.DataFrame], pd.DataFrame], optional) – A custom filtering function that takes a DataFrame as input and returns a filtered DataFrame. Default is None. Custom filters should use ‘vintage_date_forecast’ as the column name.

  • filter_point_forecasts (bool, optional) – Whether to apply the filter to point forecasts. Default is True.

  • filter_density_forecasts (bool, optional) – Whether to apply the filter to density forecasts. Default is True.

merge(other: ForecastData, compute_levels: bool = True) → None[source]#

Merge another ForecastData or DensityForecastData instance into this one.

Parameters:
  • other (ForecastData or DensityForecastData) – Another ForecastData or DensityForecastData instance to merge with this one.

  • compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts from other to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.

plot_density_vintage(variable: str, vintage_date: str | Timestamp, quantiles: list[float] | None = [0.16, 0.5, 0.84], forecast_source: list[str] | None = None, outturn_start_date: str | Timestamp | None = None, frequency: Literal['Q', 'M'] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', return_plot: bool = False, **kwargs) → tuple | None[source]#

Plot forecast density plots.

Parameters:

**kwargs – Additional keyword arguments passed to the plotting function.

Notes

This method creates density plots for the density forecasts.

sample_from_density(n_samples: int = 10000, random_state: int | None = None) → DataFrame[source]#

Generate samples from the empirical distribution defined by quantiles.

Uses inverse transform sampling to draw samples from the distribution defined by the quantile forecasts.

Parameters:
  • n_samples (int, optional) – Number of samples to generate per forecast group. Default is 10000.

  • random_state (int, optional) – Random seed for reproducibility.

Returns:

DataFrame with sampled values. Columns: [id_columns…, ‘sample_id’, ‘value’]

Return type:

pd.DataFrame

Notes

Works well when you have many quantiles (50+). With few quantiles, consider using parametric fitting instead.

Examples

>>> samples = density_data.sample_from_density(n_samples=10000, random_state=42)
>>> mean = samples.groupby(['date', 'variable'])['value'].mean()
to_point_forecast(method: str = 'median') → ForecastData[source]#

Convert density forecasts to point forecasts.

Parameters:

method (str, optional) – Method to extract point forecast: - ‘median’: Use 0.5 quantile (default, most robust) - ‘mean’: Average via sampling from distribution - specific quantile: e.g., ‘0.5’, ‘0.75’

Returns:

Point forecast data object.

Return type:

ForecastData

Examples

>>> # Convert using median
>>> point_data = density_data.to_point_forecast('median')
>>>
>>> # Convert using mean via sampling
>>> point_data = density_data.to_point_forecast('mean')
>>>
>>> # Convert using specific quantile
>>> point_data = density_data.to_point_forecast('0.75')
class forecast_evaluation.data.ForecastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, outturn_vintages: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#

Bases: PlottingMixin

Class for validation and extending forecast data.

The main method is .add_forecasts() which validates the input data and compute relevant dataframes. underscore indicates that the object only meant to be used internally.

Notes

Each ForecastData instance should only contain forecasts of a single frequency (e.g., all quarterly or all monthly). To work with multiple frequencies, create separate ForecastData instances for each frequency.

__init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, load_fer: bool | None = False, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, outturn_vintages: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#

Initialise with user data, FER data or null.

Parameters:
  • outturns_data (pd.DataFrame, optional) – DataFrame containing outturn records to add on initialisation. Default is None.

  • forecasts_data (pd.DataFrame, optional) – DataFrame containing forecast records to add on initialisation. Default is None.

  • load_fer (bool, optional) – Whether to load FER outturns and forecast data on initialisation. Default is False.

  • extra_ids (Optional[list[str]], optional) – List of extra label columns (in addition to ‘source’) present in the forecasts data. Default is None.

  • metric (str, optional) – Metric to assign to the forecasts if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.

  • compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.

  • data_check (bool, optional) – Whether to run data checks when adding forecasts. See add_forecasts() for details. Default is True.

  • outturn_vintages (bool, optional) – Whether the outturn data contains vintage information (multiple releases of the same data point over time). When False, the data is assumed to contain a single final outturn per date, and column vintage_date is not required in the outturn data. The k and latest_vintage columns in the main table will be set to sentinel values and filter_k will be a no-op. Features that depend on outturn revisions (e.g., plot_outturn_revisions, create_outturn_revisions) will raise an error. Default is True.

  • default_k (int or None, optional) – Default outturn revision index used by evaluation functions when k is omitted. If None, uses the class default.

  • first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used when the input does not provide forecast_horizon. In that case, the missing horizon is derived from target_minus_vintage and a FutureWarning is emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. Supply forecast_horizon explicitly instead.

add_benchmarks(models: list[str] | str = ['AR', 'random_walk'], variables: str | Iterable[str] | None = None, metric: Literal['levels', 'diff', 'pop', 'yoy'] = 'levels', frequency: Literal['Q', 'M'] | Iterable[Literal['Q', 'M']] | None = None, forecast_periods: int = 13, *, max_lag: Literal[1, 2] = 2, estimation_start_date: Timestamp | None = None, show_progress: bool = False) → None[source]#

Add benchmark model forecasts to the ForecastData instance.

Builds the requested benchmark models from the available outturn data and appends their forecasts to the instance via add_forecasts(). The instance is modified in place.

Parameters:
  • models (list of str or str, optional) – Benchmark model(s) to add. Valid options are "AR" (autoregressive AR(p) model) and "random_walk". Default is both (["AR", "random_walk"]).

  • variables (str, iterable of str, or None, optional) – Variable(s) to build benchmarks for. If None (default), benchmarks are built for all variables present in the outturns.

  • metric (str, optional) – Metric to build the benchmarks for. Options: "levels", "diff", "pop", "yoy". Default is "levels".

  • frequency (str, iterable of str, or None, optional) – Frequency (or frequencies) to build benchmarks for ("Q" for quarterly, "M" for monthly). If None (default), frequencies are inferred from the outturns.

  • forecast_periods (int, optional) – Number of periods to forecast ahead. Default is 13.

  • max_lag (int, optional) – Maximum number of lags (AR order) to consider when selecting the AR(p) model via BIC. Must be 1 or 2. Only applies to the "AR" model. Default is 2.

  • estimation_start_date (pd.Timestamp, optional) – The date from which to start including data for AR(p) model estimation. If None (default), all available data is used. Only applies to the "AR" model.

  • show_progress (bool, optional) – Whether to show progress bars while building the benchmarks. Default is False.

Returns:

The method modifies the ForecastData instance in place.

Return type:

None

Raises:

ValueError – If any model in models is not a recognised benchmark model.

add_fer_data() → None[source]#

Load and add FER outturns and forecast data to existing records.

add_fer_forecasts() → None[source]#

Load and add FER forecast data to existing records.

add_fer_outturns() → None[source]#

Load and add FER outturn data to existing records.

add_forecasts(df: DataFrame, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy']='levels', compute_levels: bool = True, data_check: bool = True, first_forecast_horizon: int | dict[str, int] | None=<object object>) → None[source]#

Validate new forecasts, transform forecasts and outturns and compute main table and revisions.

If any validation or transformation step fails, the instance is left unchanged.

Parameters:
  • df (pd.DataFrame) – DataFrame containing new forecast records to add.

  • extra_ids (list of str, optional) – List of extra label/identification columns (in addition to ‘source’) present in the forecasts data. Default is None.

  • metric (str, optional) – Metric to assign to the forecasts if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.

  • compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.

  • data_check (bool, optional) –

    Whether to run data checks comparing forecast values to outturns per (source, variable, metric, frequency) group. When True:

    • Horizon-zero published-target check: if rows with

      forecast_horizon == 0 match an outturn released on or before the forecast vintage at the target date, warns that the target was already published at the forecast vintage. A negative target_minus_vintage alone is not flagged because it can be a legitimate backcast caused by a publication lag. Explicitly negative forecast horizons are allowed and are not flagged by this check.

    • Vintage-distance -1 check (primary): if target_minus_vintage == -1 rows exist, each is compared to the outturn from the same vintage at the same date. Warns if the mean absolute deviation exceeds 0.5 std of the outturn series.

    • IQR ratio check (fallback): over all (date, vintage_date) pairs that overlap, warns if the forecast IQR differs from the outturn IQR by >5x.

    Detects common user errors: wrong metric column, scaling mistakes (e.g. pct*100 instead of pct), or non-real-time vintages.

    Warnings only; never raises errors. Set to False to disable. Default is True.

  • first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used only when forecast_horizon is absent. In that case, the missing horizon is derived from target_minus_vintage and a FutureWarning is emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. The argument is ignored when forecast_horizon is present. Supply forecast_horizon explicitly instead.

Notes

Outturns must be added before forecasts (call add_outturns first). All forecasts added to a ForecastData instance must have the same frequency. To work with forecasts of different frequencies, create separate ForecastData instances for each frequency. When compute_levels is True, sufficient historical outturn data is required for transformation, especially for ‘yoy’ metrics which need data from one year prior.

add_outturns(df: DataFrame, *, metric: Literal['levels', 'pop', 'yoy'] = 'levels') → None[source]#

Validate new outturns and add them to the outturns dataset

Parameters:
  • df (pd.DataFrame) – DataFrame containing new outturn records to add.

  • metric (str, optional) – Metric to assign to the outturns if ‘metric’ column is not present or contains null values. Default is ‘levels’. Options: ‘levels’, ‘pop’, ‘yoy’.

clear_filter() → None[source]#

Reset the forecasts, main and revisions tables to include all original data.

copy() → ForecastData[source]#

Return a deep copy of the ForecastData object.

create_pseudo_vintages(fill_to: str, vintage_frequency: Literal['M', 'Q'] = 'Q', publication_lags: dict[str, int] | None = None) → None[source]#

Create pseudo vintages for outturns.

Starts from the earliest available vintage in the data and fills backward to fill_to.

This method computes the publication lag from existing data and creates a full vintage structure where each vintage contains all data available at that point in time. A vintage at date X contains all data up to (X - publication_lag).

Parameters:
  • fill_to (str) – The earliest vintage date to create (i.e. how far back to fill). Format ‘YYYY-MM-DD’. Vintages are generated from this date up to the earliest existing vintage in the data.

  • vintage_frequency (str, optional) – Frequency at which to create vintages. Default is ‘Q’ (quarterly). Options: ‘M’ (monthly), ‘Q’ (quarterly).

  • publication_lags (dict[str, int] or None, optional) – A dictionary mapping variable names to their publication lag (in units of vintage_frequency). If None (default), the lag is computed from existing data.

Notes

  • Computes publication lag per variable from existing data (max_vintage - max_date)

  • Expands the dataset by creating multiple vintage records for each data point

  • Each vintage V includes all data points D where (D + lag) <= V

  • Requires outturns to already have vintage_date values to compute the lag

property df: DataFrame#

Get the main DataFrame.

Alongside the forecaster-supplied forecast_horizon, includes target_minus_vintage: the forecast target’s period distance from its vintage (date minus vintage_date, in periods at the row’s frequency). It is derived, not supplied, and is used internally for calendar/vintage geometry rather than information content.

filter(start_date: str | None = None, end_date: str | None = None, start_vintage: str | None = None, end_vintage: str | None = None, variables: str | list[str] | None = None, metrics: list[str] | None = None, sources: str | list[str] | None = None, frequencies: str | list[str] | None = None, custom_filter: Callable[[DataFrame], DataFrame] | None = None) → None[source]#

Filter the forecasts and main tables to only include data within specified date and vintage ranges, and optionally by variables, metrics, sources, or a custom filter.

Parameters:
  • start_date (str, optional) – Start date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest date.

  • end_date (str, optional) – End date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest date.

  • start_vintage (str, optional) – Start vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis starts with the earliest vintage.

  • end_vintage (str, optional) – End vintage date to filter forecasts (inclusive). Format ‘YYYY-MM-DD’. Default is None in which case the analysis ends with the latest vintage.

  • variables (str or list of str, optional) – List of variable identifiers to filter. Default is None (no filtering).

  • metrics (list of str, optional) – List of metric identifiers to filter. Default is None (no filtering).

  • sources (str or list of str, optional) – List of source identifiers to filter. Default is None (no filtering).

  • frequencies (str or list of str, optional) – List of frequency identifiers to filter. Default is None (no filtering).

  • custom_filter (Callable[[pd.DataFrame], pd.DataFrame], optional) – A custom filtering function that takes a DataFrame as input and returns a filtered DataFrame. Default is None. Custom filters should use ‘vintage_date_forecast’ as the column name.

filter_fer() → None[source]#

Filter the main dataset to only include specific variable-metric and model combinations

property forecast_required_columns: list[str]#

Get the required columns list to help the user.

property forecasts: DataFrame#

Get forecasts.

property id_columns: list[str] | None#

Get identification / labelling columns.

merge(other: ForecastData, compute_levels: bool = True) → None[source]#

Merge another ForecastData instance into this one.

Parameters:
  • other (ForecastData) – Another ForecastData instance to merge with this one.

  • compute_levels (bool, optional) – Whether to automatically transform non-levels forecasts from other to levels if outturns data is available. When True, forecasts in ‘pop’ and ‘yoy’ metrics will be converted to levels using the available outturns data. Useful if you add ‘pop’ and want to analyse ‘yoy’ forecasts and vice versa. If the transformation fails for specific groups (e.g., due to insufficient historical data), those groups will be skipped with a warning message. Default is True.

Returns:

The method modifies this instance in place.

Return type:

None

property outturn_required_columns: list[str]#

Get the required columns list to help the user.

property outturn_vintages: bool#

Whether the outturn data contains vintage information.

property outturns: DataFrame#

Get outturns.

run_dashboard(from_jupyter: bool = False, host: str = '127.0.0.1', port: int = 8000) → None[source]#

Run the Shiny dashboard with the current data.

Parameters:
  • from_jupyter (bool, optional) – Whether to run the dashboard within a Jupyter notebook. Default is False.

  • host (str, optional) – Host address for the dashboard server. Default is “127.0.0.1”.

  • port (int, optional) – Port number for the dashboard server. Default is 8000.

summary() → None[source]#

Print a summary of the forecast and outturns datasets.

For each dataset, displays: - Number of variables - List of variables with their properties - For each variable: frequency, date range, and first vintage date

property supports_outturn_revision_analysis: bool#

Whether analyses and plots requiring outturn revisions are supported.

property uses_intra_period_vintages: bool#

Whether forecast vintages are intra-period releases for the same target period.

When True, a target period has many forecast vintages and outturn releases within it, so analyses that assume one forecast per (source, horizon, period) - efficiency, forecast revision, correlation and radar analyses - do not apply, while intra-period analyses do.

class forecast_evaluation.data.NowcastData(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#

Bases: ForecastData

ForecastData subclass for nowcasting evaluation.

Designed for environments where forecasts (and outturns) are released multiple times per period with intra-period vintage dates (e.g. weekly). Non-negative information horizons are used (h=0 nowcast, h=1 one-period- ahead) so that multiple weekly vintages per horizon provide many observations for accuracy statistics. Vintage-relative backcasts are identified by target_minus_vintage instead.

Differences from ForecastData:

  • The main table includes a days_to_publication column computed as (vintage_date_outturn - vintage_date_forecast).days, which can be used for intra-period accuracy analysis.

  • Efficiency analyses (weak/strong efficiency, Blanchard-Leigh, revision predictability, revisions-errors correlation) are not available.

Notes

Two different time axes appear in nowcast analysis and should not be confused:

  • days_to_publication (this class) is the distance from the forecast vintage to the release date of the selected outturn vintage. It therefore depends on k and on the publication lag of the series.

  • days_to_period_end is the distance from the forecast vintage to the end of the target period, independent of when the outturn is published.

The two differ by the publication lag. Intra-period accuracy and bias functions take an axis argument ('period_end', the default, or 'publication') to choose between them, and bin the result to the nearest 7 days.

__init__(outturns_data: DataFrame | None = None, forecasts_data: DataFrame | None = None, *, extra_ids: list[str] | None = None, metric: Literal['levels', 'pop', 'yoy'] = 'levels', compute_levels: bool = True, data_check: bool = True, default_k: int | None = None, first_forecast_horizon: int | dict[str, int] | None = None)[source]#

Initialise NowcastData.

Parameters:
  • outturns_data (pd.DataFrame, optional) – DataFrame containing outturn records.

  • forecasts_data (pd.DataFrame, optional) – DataFrame containing forecast records.

  • extra_ids (list of str, optional) – Extra label columns in addition to ‘source’.

  • metric (str, optional) – Default metric if not present in the data. Default is ‘levels’.

  • compute_levels (bool, optional) – Whether to auto-transform non-levels forecasts to levels.

  • data_check (bool, optional) – Whether to run data checks when adding forecasts.

  • first_forecast_horizon (int or dict[str, int], optional) – DEPRECATED legacy value used when forecast_horizon is absent. In that case, the missing horizon is derived from target_minus_vintage and a FutureWarning is emitted. If this argument is omitted too, the same deprecated fallback is used without a shift. Supply forecast_horizon explicitly instead.

add_benchmarks(*args, **kwargs)[source]#

Add benchmark model forecasts to the ForecastData instance.

Builds the requested benchmark models from the available outturn data and appends their forecasts to the instance via add_forecasts(). The instance is modified in place.

Parameters:
  • models (list of str or str, optional) – Benchmark model(s) to add. Valid options are "AR" (autoregressive AR(p) model) and "random_walk". Default is both (["AR", "random_walk"]).

  • variables (str, iterable of str, or None, optional) – Variable(s) to build benchmarks for. If None (default), benchmarks are built for all variables present in the outturns.

  • metric (str, optional) – Metric to build the benchmarks for. Options: "levels", "diff", "pop", "yoy". Default is "levels".

  • frequency (str, iterable of str, or None, optional) – Frequency (or frequencies) to build benchmarks for ("Q" for quarterly, "M" for monthly). If None (default), frequencies are inferred from the outturns.

  • forecast_periods (int, optional) – Number of periods to forecast ahead. Default is 13.

  • max_lag (int, optional) – Maximum number of lags (AR order) to consider when selecting the AR(p) model via BIC. Must be 1 or 2. Only applies to the "AR" model. Default is 2.

  • estimation_start_date (pd.Timestamp, optional) – The date from which to start including data for AR(p) model estimation. If None (default), all available data is used. Only applies to the "AR" model.

  • show_progress (bool, optional) – Whether to show progress bars while building the benchmarks. Default is False.

Returns:

The method modifies the ForecastData instance in place.

Return type:

None

Raises:

ValueError – If any model in models is not a recognised benchmark model.

add_fer_data()[source]#

Load and add FER outturns and forecast data to existing records.

add_fer_forecasts()[source]#

Load and add FER forecast data to existing records.

add_fer_outturns()[source]#

Load and add FER outturn data to existing records.

add_forecasts(df, **kwargs)[source]#

Add forecasts, aligning outturn vintages to forecast vintages first.

Alignment mutates the outturns before the parent validates the input, so the rollback discards those snapshots if the forecasts are rejected.

add_outturns(df, **kwargs)[source]#

Add outturns, then normalise the internal _aligned marker column.

Genuine new outturn releases never carry the _aligned marker (it is only set by _align_outturn_vintages for forward-filled snapshots). Concatenating them with existing aligned rows can introduce NaNs in this Boolean column, which would break ~outturns["_aligned"] expressions elsewhere. Treat missing values as False (i.e. not aligned).

clear_filter() → None[source]#

Reset the forecasts, main and revisions tables to include all original data.

Overrides the parent implementation to reapply the nowcast-specific k revision index and days_to_publication column, which the parent’s calendar-based rebuild does not preserve.

create_pseudo_vintages(*args, **kwargs)[source]#

Create pseudo vintages for outturns.

Starts from the earliest available vintage in the data and fills backward to fill_to.

This method computes the publication lag from existing data and creates a full vintage structure where each vintage contains all data available at that point in time. A vintage at date X contains all data up to (X - publication_lag).

Parameters:
  • fill_to (str) – The earliest vintage date to create (i.e. how far back to fill). Format ‘YYYY-MM-DD’. Vintages are generated from this date up to the earliest existing vintage in the data.

  • vintage_frequency (str, optional) – Frequency at which to create vintages. Default is ‘Q’ (quarterly). Options: ‘M’ (monthly), ‘Q’ (quarterly).

  • publication_lags (dict[str, int] or None, optional) – A dictionary mapping variable names to their publication lag (in units of vintage_frequency). If None (default), the lag is computed from existing data.

Notes

  • Computes publication lag per variable from existing data (max_vintage - max_date)

  • Expands the dataset by creating multiple vintage records for each data point

  • Each vintage V includes all data points D where (D + lag) <= V

  • Requires outturns to already have vintage_date values to compute the lag

filter_fer()[source]#

Filter the main dataset to only include specific variable-metric and model combinations

merge(other: ForecastData, compute_levels: bool = True) → None[source]#

Merge another instance into this one, excluding synthetic outturn snapshots.

The parent implementation passes other._raw_outturns straight through add_outturns, which strips the _aligned marker (it isn’t part of the outturn schema). Forward-filled snapshots built by _align_outturn_vintages would then be indistinguishable from genuine releases and could corrupt revision indices and outturn-revision analyses.

This override merges only other’s genuine outturn releases (_aligned is False or absent). Forecasts are merged as usual; add_forecasts (overridden above) regenerates aligned snapshots and recomputes k / days_to_publication for the merged data.

property uses_intra_period_vintages: bool#

Whether forecast vintages are intra-period releases for the same target period.

forecast_evaluation.data.create_sample_forecasts() → DataFrame[source]#

Create sample forecasts DataFrame for testing and examples.

forecast_evaluation.data.create_sample_nowcast_forecasts() → DataFrame[source]#

Create sample nowcasting forecasts with weekly vintage dates.

Generates nowcasts (2020-2025) from two models for two variables (gdp and cpi). Vintages are produced once per week across the full sample. Each vintage targets two consecutive releases:

  • h = 1 (forecast): the next quarter (not yet started or in progress).

  • h = 0 (nowcast): the current quarter (in progress).
    • the previous quarter while its official outturn has not yet been

      published (gdp: 6 weeks after quarter-end; cpi: 2 weeks after quarter-end). Once the data is released, that vintage-relative path stops.

Forecast errors converge toward zero as the vintage date approaches the end of the target quarter, with additive noise so that convergence is realistic rather than perfectly monotonic.

Returns:

DataFrame with columns: date, variable, vintage_date, source, frequency, value, and the explicitly supplied forecast_horizon.

Return type:

pd.DataFrame

Examples

>>> df = create_sample_nowcast_forecasts()
>>> df["source"].unique()
array(['nowcast_dfm', 'nowcast_bridge'], dtype=object)

Visualize how forecasts evolve over weekly vintages:

>>> # Import the plotting function from the end of this module
>>> import matplotlib.pyplot as plt
>>> from forecast_evaluation.data.sample_data import plot_sample_nowcasts
>>> plot_sample_nowcasts()  # Plots forecasts by horizon, colored by vintage date
forecast_evaluation.data.create_sample_nowcast_outturns() → DataFrame[source]#

Create sample outturns DataFrame for nowcasting tests and examples.

Creates quarterly outturns for two variables (gdp and cpi) with multiple outturn vintages, covering 2020Q1 to 2025Q4 (24 quarters).

Publication lags and revision frequencies are realistic:

  • gdp: first release 6 weeks (42 days) after the end of the target quarter, then revised once per quarter at each subsequent quarter-end.

  • cpi: first release 2 weeks (14 days) after the end of the target quarter, then revised monthly (14 days after each subsequent month-end).

For each target quarter, the outturn data has:

  • A first-release vintage at the publication date.

  • Subsequent revision vintages (quarterly for GDP, monthly for CPI) up to 2026-03-31, with white noise shrinking as the vintage matures.

The realistic first-release dates mean that intra-quarter nowcast vintages before the publication date have no backcast (h=-1) outturn available for pairing, while later vintages within that quarter do.

Returns:

DataFrame with outturn data suitable for nowcasting evaluation.

Return type:

pd.DataFrame

forecast_evaluation.data.create_sample_outturns() → DataFrame[source]#

Create sample outturns DataFrame for testing and examples.