How-to guides

Complete a specific task with the public panel APIs

These recipes assume familiarity with the estimate panel. The executable examples use the same fixtures as the tutorials. In application code, replace those fixtures with the caller’s estimate panel.

Publish an anchored feed

  • Inputs: Supply a long panel, an exclusive UTC reading moment, the forecast source name and externally fitted parameters.
  • Parameter dates: The training window must end before the publication date.
  • Output selection: Request expected_surprise for a fraction relative to consensus. Request anchored_level separately when a level is needed.
import pandas as pd
import pf as examples
import postforecast as pfc

estimates = examples.example_panel()
parameters = pfc.AnchoringParameters.model_validate(
    pfc.STUDY_2025_01.model_dump(mode="json")
)
feed = pfc.publish_anchored(
    estimates,
    pd.Timestamp("2026-01-20", tz="UTC"),
    forecast_source="model",
    parameters=parameters,
    fields=("expected_surprise",),
)
feed[["entity", "period", "expected_surprise", "eligible", "eligibility_reason"]]
entity period expected_surprise eligible eligibility_reason
0 ZS 2026Q1 0.032968 True publishable
  • Real parameters: Replace the tutorial’s shipped parameter payload with the approved artifact for the consuming application. File loading stays with the caller.
  • Explicit universe: Pass subjects= to retain requested subjects even when they have no known observations. Refused subjects keep a row and a reason.
  • Units: A surprise of 0.03 means 3%. Raw source levels are excluded from this publication API.
  • Reading policy: Publication uses the reference 30-day revision with a 60-day maximum age at each revision read. Use prepare_anchored_subjects and AnchoredEstimate when a different preparation policy is required.

Configure Bayesian predictions

Use bayesian_kpi_predictions for the complete reference workflow. The panel needs reported actuals and historical estimates as well as live predictions.

history = examples.quarterly_history()
as_of = pd.Timestamp("2026-05-10", tz="UTC")
settings = pfc.BayesianPredictionSettings(
    version="independent-example",
    method="independent",
    series="predictions",
    values=("prediction", "posterior-growth", "prediction-lower", "prediction-upper"),
)
predictions = pfc.bayesian_kpi_predictions(
    history,
    as_of,
    forecast_source="model",
    settings=settings,
)
predictions[["entity", "period", *settings.values, "eligible"]]
entity period prediction posterior-growth prediction-lower prediction-upper eligible
0 ZS 2026-06 800.648824 0.049481 771.795162 832.480391 True
  • Historical output: Set series="backtests" for historical estimates fitted on strictly earlier observations. Set series="combined" for the stitched series.
  • Separate model histories: Pass backtest_source= when historical model estimates have a different source identifier from live predictions.
  • Training start: Set start_date in the settings to restrict the training sample. Filter display dates after calculation to retain the intended history.
  • Dispersion weighting: Set stdev_weighted_consensus=True and supply consensus dispersion. Count weighting additionally uses estimate_count and consensus_count_exponent. See the precision rules.
  • Publication horizons: For the independent method, set relative_to="publish" and a nonpositive relative_days, or "latest". Pass a publications frame with subject keys and UTC publication_date. See the publication-relative contract.

To use correlation adjustment, construct compatible settings:

correlated_settings = pfc.BayesianPredictionSettings(
    version="correlation-example",
    method="correlation adjusted",
    series="predictions",
    values=("prediction",),
)
correlated = pfc.bayesian_kpi_predictions(
    history,
    as_of,
    forecast_source="model",
    settings=correlated_settings,
)
correlated[["entity", "period", "prediction", "eligible", "eligibility_reason"]]
entity period prediction eligible eligibility_reason
0 ZS 2026-06 812.084193 True eligible
  • Required model: Correlation adjustment requires model observations.
  • Supported output: Only prediction is available for this method.
  • Unsupported options: Dispersion weighting and publication-relative horizons are rejected. See the complete restrictions.

Inspect refusals

Use eligible as the publication verdict and retain eligibility_reason for diagnosis. Do not substitute consensus or zero for a refused result.

missing_model = estimates.loc[estimates.source != "model"]
refused = pfc.publish_anchored(
    missing_model,
    pd.Timestamp("2026-01-20", tz="UTC"),
    forecast_source="model",
    parameters=parameters,
    fields=("expected_surprise",),
)
refused.loc[~refused.eligible, ["entity", "period", "eligibility_reason"]]
entity period eligibility_reason
0 ZS 2026Q1 missing_input
  • Malformed panel: PanelError reports a contract violation; correct the input before calling again.
  • Anchored refusal: Requested numeric outputs are missing and the subject remains in the result.
  • Bayesian refusal: Diagnostics can remain populated even when the prediction is unavailable. A finite diagnostic alone does not make a row publishable.
  • Missing interval: The independent reference can produce a prediction without an interval when model precision is unavailable. See the independent reference.

Retain an audit record

Store the complete parameter or settings payload alongside the output. A version identifier alone cannot reconstruct the calculation.

parameter_record = parameters.model_dump(mode="json")
settings_record = settings.model_dump(mode="json")
parameter_record
{'customary_beat': 0.0112,
 'gap_weight': 0.129,
 'revision_weight': 1.28,
 'maximum_absolute_gap': 0.25,
 'maximum_prediction_age': 'P21D',
 'maximum_consensus_age': 'P60D',
 'version': 'study-2025-01',
 'fitted_through': '2024-12-31'}
  • Inputs: Retain the input snapshot or its reproducible identifier, the reading moment and the source identifiers in the consuming application.
  • Parameters: Keep the full payload, its version and fitted-through date when applicable. Settings chosen rather than fitted have no fitted-through date.
  • Software: Record the installed package revision alongside the run.
  • Outputs: Preserve subject keys, method, version and refusal status when combining results across sources or parameter sets.
  • Persistence: The caller writes the record; the library performs no file or network I/O.