nautechsystems/nautilus_trader · error

Invalid `confidence` for `ValueAtRisk`

Error message

Invalid `confidence` for `ValueAtRisk`

What it means

ValueAtRisk::new is the infallible constructor for the ValueAtRisk statistic. It delegates to new_checked and unwraps the Result with expect(), so it panics whenever the supplied confidence level is not finite or lies outside the open interval (0, 1). The panic guards the mathematical validity of the VaR calculation, which requires a probability strictly between 0 and 1.

Source

Thrown at crates/analysis/src/statistics/value_at_risk.rs:84

    ///
    /// 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 [`ValueAtRisk`] 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 `ValueAtRisk`")
    }
}

impl Display for ValueAtRisk {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Value at Risk (confidence {})", self.confidence)
    }
}

/// Returns the `q`-th percentile (`q` in `[0, 100]`) of `sorted_values` using
/// linear interpolation between closest ranks, matching `numpy.percentile`.
///
/// `sorted_values` must be sorted ascending and non-empty.
pub(crate) fn percentile_linear(sorted_values: &[f64], q: f64) -> f64 {
    debug_assert!(
        !sorted_values.is_empty(),
        "percentile requires a non-empty slice"
    );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass a finite value strictly between 0 and 1, e.g. 0.95 or 0.99 for the confidence level
  2. If the config stores percentages, divide by 100 before constructing ValueAtRisk
  3. Use ValueAtRisk::new_checked(confidence) instead and handle the Err to avoid the panic
  4. Validate the parsed config field (finite and 0 < c < 1) at startup before reaching the constructor

Example fix

// before
let var = ValueAtRisk::new(Some(confidence_percent)); // 95.0 -> panic
// after
let var = ValueAtRisk::new(Some(confidence_percent / 100.0)); // 0.95
// or non-panicking:
let var = ValueAtRisk::new_checked(Some(confidence))
    .expect("confidence must be in (0, 1)");
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_confidence(c: f64) -> bool {
    c.is_finite() && c > 0.0 && c < 1.0
}
assert!(is_valid_confidence(confidence), "confidence must be in (0, 1)");
let var = ValueAtRisk::new(Some(confidence));

Type guard

fn is_valid_confidence(c: Option<f64>) -> bool {
    matches!(c, Some(v) if v.is_finite() && v > 0.0 && v < 1.0) || c.is_none()
}

Try / catch

let var = match ValueAtRisk::new_checked(Some(confidence)) {
    Ok(v) => v,
    Err(e) => { log::error!("invalid confidence: {e}"); return Err(e); }
};

Prevention

When it happens

Trigger: Calling ValueAtRisk::new with Some(f64) where the value is NaN, INFINITY, 0.0, 1.0, negative, or >= 1.0 (e.g. ValueAtRisk::new(Some(0.95).ok) is fine but Some(1.0) or Some(f64::NAN) panic). Also triggered by passing a percentage like 95.0 instead of the fraction 0.95.

Common situations: Config mistakes where a confidence level is read from YAML/JSON as '95' (percent) rather than 0.95; unit-config values parsed as f64 producing out-of-range or NaN values from empty/invalid strings; arithmetic producing inf (e.g. division by zero) before constructing the estimator.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d8d0373e86805353. Report an issue: GitHub.