Skip to main content
A method is one class holding the calibration math and the orchestration around it: it takes forecasts and truths, and returns an interval. Seven ship with conformalforecast, and they divide cleanly in two. Offline methods calibrate once on a block of past errors and then apply a fixed correction. They are the classical conformal guarantee, and they assume the calibration errors and the future errors are exchangeable — that the world does not change between the two. Online and adaptive methods keep learning after calibration. Each consumes update(prediction, truth) as observations arrive and moves its own knobs in response. They exist because time series break exchangeability routinely: regimes shift, variance drifts, a model that was well-calibrated last quarter is not this one.

The seven

Each method is configuration, and calibrating it returns a fitted object. The pages below drive the forecaster surface — fitted = method.calibrate_cv(forecaster, n_windows) then fitted.predict(history) — because that is what standalone users want. The array surface, fitted = method.fit(predictions, truths) then fitted.interval(predictions), takes no forecaster at all; see Architecture for the split and Embedding for when to reach for it.

Choosing one

Work down this list and stop at the first line that describes your problem.
  1. You have never used conformal prediction here before. Start with split conformal. It is one page of math, it has no knobs, and its coverage is a theorem rather than a hope. Everything else on this list is a response to a way it can fail — measure that failure before you fix it.
  2. Your errors are much larger at some times than others — a seasonal peak, a high-volume series in a panel — and a constant-width band is too wide most of the year and too narrow at the peak. Use CQR, if your forecaster can emit quantiles. Constant-width is a property of the score, not of conformal prediction.
  3. Your measured coverage drifts away from target over time. The world moved. Use an online method:
    • ACI if you are willing to tune one learning rate, and want the simplest thing that provably recovers long-run coverage.
    • AgACI if you are not — it runs several learning rates at once and aggregates them, which is usually what you want in production.
    • NexCP if you would rather express “recent errors matter more” as a decay on the calibration set than as a moving target.
  4. You are predicting a different domain than you calibrated on — a new region, a new customer segment, a shifted operating range — and the difference shows up in features you can measure, not in the same panel drifting under you over time. That is the boundary against item 3: temporal drift on a fixed panel is an online-method problem, a domain that differs in measurable ways is this one. Use weighted split conformal, which needs either target features (adapt(weighting=DensityRatio(...), target_X=...)) or target labels (recalibrate()). See Transfer and adaptation for the full set of verbs and which one your data allows.
  5. Coverage is fine on average but wrong in identifiable places — the interval is too wide in calm periods and too narrow in volatile ones. That is a conditional-coverage problem. Use SPCI, which fits a quantile regressor on the residual history and lets the width move with it.
Two of those choices have an asymmetric mode, which is a setting rather than a different method, so it does not get its own line above. Reach for it when the two tails do not cost the same — being short on inventory is not the mirror image of being long on it — or when the forecaster is biased and you would rather the band shifted than widened on both sides. Split conformal with symmetric=False scores signed residuals and takes one one-sided quantile per tail; it needs no extra capability, works through every adapter, and costs more calibration data, since each tail now enforces its own ceil(1 / level) floor. CQR with the same flag tilts the quantile levels it requests instead, which tracks asymmetry that varies with the input rather than applying a constant offset — but no shipped Nixtla adapter can serve those levels today.
Coverage is not the only thing to measure Two methods can both hit 90% and differ enormously in usefulness: the wider one is trivially valid and tells you nothing. Compare width alongside coverage — the Winkler score in Diagnostics does exactly that, penalising width and misses on one scale.

The guarantee, and its limits

Split conformal gives finite-sample marginal coverage under exchangeability: for any forecaster, P(y ∈ interval) ≥ 1 - alpha. Three qualifiers matter in practice.
  • Marginal, not conditional. The probability is over draws, averaged across series and horizons. A particular series can be systematically under-covered while the average is exactly right.
  • Exchangeability rarely holds for time series. The calibration residuals come from the past and the test residual comes from the future; if the process drifts, they are not exchangeable and the guarantee degrades. The online methods on this page replace it with a weaker but more honest long-run guarantee.
  • Finite calibration sets quantise the achievable coverage. With n calibration windows the attainable levels are multiples of 1/(n+1), which is why every method demands at least ceil(1/alpha) effective windows per series (asymmetric split and SPCI demand more) and raises InsufficientCalibrationSamples otherwise.