What it does
The forecaster supplies a lower and upper quantile,q_lo and q_hi,
at levels alpha/2 and 1 - alpha/2. The nonconformity score asks how
far outside that band the truth fell:
E is negative when the truth landed comfortably inside, positive when
it fell outside. Take the exact conformal quantile Q of the
calibration Es and widen — or, if the model was over-cautious,
narrow — the band:
Worked example
AutoETS produces analytical prediction intervals, which
StatsForecastAdapter exposes as quantiles. That makes it
quantile-capable, so it can back CQR.
Not every adapter canConformalizedQuantileRegressiondeclaresSupportsQuantilesin itsREQUIRED_CAPABILITIES, and the check runs where the forecaster is bound — the first thing bothcalibrateandcalibrate_cvdo.MLForecastAdapterdoes not implement quantiles, so calibrating CQR on one raisesUnsupportedCapabilitybefore any forecasting happens, rather than failing later insidepredict.NeuralForecastAdaptersupports it only when the model’s loss is a quantile loss such asMQLoss— it overridessupports()to inspect the loss, so the same class passes or fails depending on how it was trained.
calibrate_cv noticed that the method CONSUMES_QUANTILES and asked
the adapter for a quantile cross-validation rather than a point one.
You never request that yourself.
statsforecast quantile rules Quantiles must arrive in symmetric pairs, andq == 0.5is rejected — the level API statsforecast exposes has no median column.alpha=0.1becomes the pair(0.05, 0.95)automatically, which is whatquantile_levelsshows above. You only choose levels yourself when you passsymmetric=Falsewith explicitalpha_loandalpha_hi.
What conformalizing changed
Compare three bands on the same axis: the rawAutoETS quantiles, the
same quantiles after CQR, and a split-conformal band for reference.

AutoETS’s analytical 90% band averaged 92 passengers
wide and was too confident, so the conformal quantile came out positive.
Had the model been over-cautious the score would have been negative and
CQR would have pulled the band in — the move split conformal cannot
make, because an absolute residual is never negative.
Measured coverage
Asymmetric intervals
By default CQR requests thealpha/2 and 1 - alpha/2 quantiles from
the forecaster. When the cost of being too low differs from the cost of
being too high — inventory, staffing, capacity planning — request an
off-centre pair with symmetric=False. The levels move the band’s width
and position, not its validity: one conformal quantile of the CQR score
is added to both sides, so the guarantee is joint coverage 1 - alpha
whatever the levels are, with no per-tail guarantee. By convention the
pair still satisfies alpha_lo + (1 - alpha_hi) = alpha:
No shipped Nixtla adapter can serve asymmetric levels in v0.1 That snippet is not executed on this page, because it would fail with any of the three Nixtla adapters — statsforecast, mlforecast and neuralforecast alike. The constraint is not in CQR. The method accepts any0 < alpha_lo < 0.5 < alpha_hi < 1withalpha_lo + (1 - alpha_hi) = alpha, and its array surface never learns which levels produced its inputs. It is in the bridge to the Nixtla libraries: all three expose intervals through an integerlevelAPI, wherelevel=90means the 5th and 95th percentiles inseparably. The shared helperadapters/_nixtla_common.quantiles_to_levelstherefore rejects any quantile whose mirror is absent:Training a neuralforecast model withMQLoss(quantiles=[0.02, 0.92])does not help — the adapter still requests those quantiles throughlevel=, and raises the same error before the model is consulted. What does work is an adapter that implementsSupportsQuantilesdirectly and serves arbitrary levels, bypassing the level API. That is a dozen lines on top of your own model;tests/helpers.pyhas a working example, and Adapters covers the contract. Until a Nixtla adapter grows a non-level quantile path, that is the only route to an asymmetric interval from CQR. It is not the only route to an asymmetric conformal interval.SplitConformal(symmetric=False, alpha_lo=..., alpha_hi=...)takes one one-sided conformal quantile of the signed residual per tail, so it needs no quantile capability at all and works through every adapter, the three Nixtla ones included. What it buys is different, though: its two offsets are constants added to the point forecast, so it corrects a forecaster that is consistently biased, while CQR’s quantiles track skew that varies with each input. Reach for it when one tail carries the real cost and a fixed shift is enough; reach for CQR when the asymmetry itself depends on the features.
When not to use it
- Your forecaster has no quantiles. Most gradient-boosting setups through mlforecast do not, and CQR will refuse the moment you calibrate. Use split conformal, or SPCI if you want varying width without a quantile-capable model.
- Your coverage drifts over time. CQR is offline: it calibrates once. Pair the diagnosis with ACI or NexCP.
References
Y. Romano, E. Patterson, and E. J. Candès, “Conformalized Quantile Regression,” 2019. [Online]. Available: https://arxiv.org/abs/1905.03222.Next
- ACI — the first online method, for coverage that drifts.
- SPCI — varying width from a residual model rather than a quantile model.
- Methods overview — the decision guide.

