nautechsystems/nautilus_trader · error
Invalid `confidence` for `ExpectedShortfall`
Error message
Invalid `confidence` for `ExpectedShortfall`
What it means
ExpectedShortfall::new is the infallible constructor wrapping new_checked, which validates that confidence is finite and strictly within (0, 1) (e.g. 0.95 or 0.99). The expect panics when the supplied value fails validation, since the panicking constructor is meant for known-good constants.
Source
Thrown at crates/analysis/src/statistics/expected_shortfall.rs:83
///
/// Returns an error if `confidence` is not finite and in the range `(0, 1)`.
pub fn new_checked(confidence: Option<f64>) -> anyhow::Result<Self> {
let confidence = confidence.unwrap_or(0.95);
check_predicate_true(
confidence.is_finite() && confidence > 0.0 && confidence < 1.0,
"confidence must be finite and in the range (0, 1)",
)?;
Ok(Self { confidence })
}
/// Creates a new [`ExpectedShortfall`] instance.
///
/// # Panics
///
/// Panics if `confidence` is not finite and in the range `(0, 1)`.
#[must_use]
pub fn new(confidence: Option<f64>) -> Self {
Self::new_checked(confidence).expect("Invalid `confidence` for `ExpectedShortfall`")
}
}
impl Display for ExpectedShortfall {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Expected Shortfall (confidence {})", self.confidence)
}
}
impl PortfolioStatistic for ExpectedShortfall {
type Item = f64;
fn name(&self) -> String {
self.to_string()
}
fn calculate_from_returns(&self, raw_returns: &Returns) -> Option<Self::Item> {
if !self.check_valid_returns(raw_returns) {View on GitHub (pinned to 18893faf8b)
Solutions
- Pass confidence as a fraction strictly between 0 and 1 (e.g. 0.99, not 99).
- Validate/clamp the config value before constructing: require x.is_finite() && 0.0 < x && x < 1.0.
- Use ExpectedShortfall::new_checked(...) and handle the Result instead of the panicking new().
Example fix
// before let es = ExpectedShortfall::new(Some(95.0)); // panics: 95 not in (0,1) // after let es = ExpectedShortfall::new(Some(0.95));
Defensive patterns
Strategy: validation
Validate before calling
# python caller guard confidence = config["confidence"] # e.g. 95 meaning percent confidence = confidence / 100.0 if confidence > 1.0 else confidence assert 0.0 < confidence < 1.0, "confidence must be in (0, 1)" es = ExpectedShortfall(confidence)
Type guard
fn valid_confidence(c: f64) -> bool { c.is_finite() && c > 0.0 && c < 1.0 } Try / catch
# Rust side: prefer the checked constructor
match ExpectedShortfall::new_checked(Some(c)) {
Ok(es) => es,
Err(e) => { log::error!("bad confidence {c}: {e}"); ExpectedShortfall::new(None) }
} Prevention
- Always express confidence as a fraction in (0, 1), never a percentage.
- Validate config-sourced floats with is_finite() and range checks before constructing statistics.
- Prefer the *_new_checked constructors when values come from user input.
When it happens
Trigger: Calling ExpectedShortfall::new with Some(x) where x <= 0, x >= 1, or x is NaN/infinity; also None default path if its internal default were invalid (it is not, so practically only bad Some values).
Common situations: Confidence expressed as a percentage (95.0 instead of 0.95); reading the value from config as '95%' string remainder; NaN propagating from parsed config or computed parameters.
Related errors
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/69e99c22bf5366d2.
Report an issue: GitHub.